Çok basit koddan “Yasadışı donanım talimatı”


9

Şüpheli bir iddiayı araştırırken , bu küçük test programını yazdımnoway.c

int proveit()
{
    unsigned int n = 0;
    while (1) n++;
    return 0;
}

int main()
{
    proveit();
    return 0;
}

Bunu test, anladım:

$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction  ./a.out

Wat.

Optimizasyon olmadan derlersem beklendiği gibi askıda kalıyor. Meclise baktım ve tüm çan ve ıslık olmadan mainfonksiyon şöyle görünüyor:

_main:                                  ## @main
    pushq   %rbp
    movq    %rsp, %rbp
    ud2

ud2Görünüşe göre nerede tanımsız davranış için bir talimattır. Yukarıda sözü edilen şüpheli iddia olan "Asla geri dönmeyen bir işlev UB'dir". Yine de inanmakta zorlanıyorum. Gerçekten mi!? Sıkma döngüsünü güvenle yazamaz mısınız?

Sanırım sorularım:

  1. Bu olup bitenler hakkında doğru bir okuma mı?
  2. Öyleyse, biri beni doğrulayan resmi bir kaynağa yönlendirebilir mi?
  3. Bu tür bir optimizasyonun gerçekleşmesini istediğiniz durum nedir?

Alakalı bilgi

$ clang --version
Apple clang version 11.0.0 (clang-1100.0.20.17)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

3
IIRC, imzalı int taşması UB'dir.
wildplasser

1
^^^^ ie int n = 0===> unsigned int n = 0;ya da daha iyisi ..while (1);
WhozCraig

1
Hmmm ... Derleyici Explorer clang, -O gcc.godbolt.org/z/NTCQYT ve onsuz satır çeviri ile kendi kendine hedef atlama talimatı alır . Birçok versiyonda tutarlı görünüyor. Ama aynı zamanda (yine de bakmayacağım), C standardının, yan etkisizse sonlandırmanın ub olduğunu söylediğini hatırlıyorum . Hans Boehm, bunun başka türlü imkansız derleyici optimizasyonlarına izin verdiğini açıklıyor: open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm
Gene

1
Undefined davranışı, sonsuz döngü değil, tamsayı taşması olarak işaretlenir. unsigned int
MM

2
@Gene Bunu söylediğini sanmıyorum. Sabit olmayan kontrol ifadelerine sahip yan etkisiz döngülerin sonlandığı varsayılabilir ( port70.net/~nsz/c/c11/n1570.html#6.8.5p6 ), ancak meşgul döngüsü iyi olmalıdır. UB talimatı ile örnek çoğaltamam rağmen UB tamsayı taşması var.
PSkocik

Yanıtlar:


4

Şimdi söz konusu olan kod için ud2'yi alırsanız, derleyici uygun bir C derleyicisi değildir. Bir derleyici hatası bildirebilirsiniz.

C ++ bu kod aslında UB olacağını unutmayın. İş parçacıkları eklendiğinde (sırasıyla C11 ve C ++ 11), çok iş parçacıklı olmayan bir programın ana yürütme iş parçacığı da dahil olmak üzere, herhangi bir iş parçacığı için ileri ilerleme garantisi verilmiştir.

C ++ 'da istisnalar olmaksızın tüm evreler sonunda ilerlemelidir. Ancak C'de kontrol ifadesi sabit bir ifade olan bir döngü ilerlemek için gerekli değildir. Anladığım kadarıyla, C'nin bu istisnayı eklediği, çünkü gömülü kodlamada while(1) {}, iş parçacığını asmak için a kullanmak zaten yaygın bir uygulamadır .

Daha detaylı cevapları olan benzer bir soru


Evet ud2C kodu almak, ama C ++ ileri ilerleme garantisi (araştırma yapabileceğim bir terim) hakkında bilgi dahil ettiğiniz için teşekkür ederim hangi gerçekten soruyordum ama uh, optimize olarak var Soruyu hazırlıyordum.
luqui

Standartlar Komitesinin söylemeye çalıştığını düşündüğüm şeylerin daha iyi bir ifadesi, belirli bir işlemden sonraki bir döngü içindeki her şeyi ertelemek, program davranışını gözle görülür şekilde etkilemez, döngünün bir geçmiş olarak yürütülmesinin ertelenmesi, gözlemlenebilir davranış değişikliği.
supercat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.