2012-10-25 27 views
13

Ben (çabuk) bazı kod yazmak ve kazara scanf() bağımsız değişkenleri ters:Ters argümanlar()

char i[] = "ABC1\t"; 
scanf(i, "%s"); 

bu bir bit şikayet etmez gcc -Werror -Wall -Wextra ile derleniyor. Açıkçası, bu kod işe yaramıyor, ama neden bana argümanları tersine çevirdiğimi bildirmedi? i'un bir biçim dizesi olmadığını veya ikinci bağımsız değişkenin depolanabilir bir tür olmadığını algılayamaz mı?

DÜZENLEME tüm fikir için
Teşekkür, cevabı buldum gibi bu "catchable"

cevap

17

Ha! Buldum. -Wformat=2 bayrağı ile gcc isabet yakaladı.

başkalarının başvuru için bilgiler yayınlamak: Burada

öyle ki, ben -Wall üstlenmişti list of flags I found

-Wformat Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified...

içinde -Wformat vardı, ama gerçekten önemli parçası nedir ben sadece Bulunan:

-Wformat is included in -Wall. For more control over some aspects of format checking, the options -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, and -Wformat=2 are available, but are not included in -Wall.

+0

Evet, +1 Ben de onu arıyordum. – Omkant

8

(aşağıdaki başvurmak için yayınlanmıştır) yapar -Wformat bayrağına büküm bunu herhalde orada görünüyor yapmamalısın.

int scanf (const char * format, ...); 

i

normalde const char* dönüştürüldü, gerisi parametreler sadece "üç nokta" ve derleme zamanında kontrol edilemez.

+1

The hea GCC tarafından kullanılan dersler genellikle bir format dizgesi olarak işaretlenmiş ilk parametreye sahiptir ve daha sonra '-Wformat' sağlandığında, doğru tiplerin kalan parametrelere geçtiğinden emin olabilir. Bunun bir parçası olduğunu düşünüyorum -Wall'. – Will

+1

@Will Ama sonra tekrar - bir const olmayan char * bir biçim dizesi (kendi başına geçerli) olarak geçirildi ve böylece derleyici parametre kontrolünü zorlamadı. Biçim dizgisi 'const char *' veya literal ise böyledir. – Lyth

+0

Muhtemelen 'char * fmt' & 'const char * fmt' arasında bir kontrol yoktur. Ikinci argüman ("ABC \ t") char * veya const char * olacaksa, herkes söyleyebilir mi? – anishsane

3

scanf (adam scanf) için manuel giriş prototip verir:

int scanf(const char *format, ...); 

Bir Char [] İlk argüman memnun yani char * sadece özel bir türüdür. İkincil argümanlar çalışma zamanında değerlendirilir (eğer hatırlarsam), bu yüzden derleyici tarafından bile dikkate alınmaz. Derleyicinin geleceğinden, bu prototip verilen işlevi için iyi bir çağrıdır.

Ayrıca, derleyici, geçersiz konumlara yazmaya çalıştığınızı hiçbir zaman denetlemez. C ile ilgili müthiş (ya da) şey, istediğin şey kötü bir fikir olsa bile, ne istersen yapmanı sağlar.

+2

'scanf'in kendisi tarafından kabul edildiği doğrudur, fakat glibc'de gcc ile derlenmiş, scanf' __attribute __ ((format (scanf, 1, 2))) 'dır, bu da derleyiciye parametrelerin doğru olduğundan emin olmasını söyler. Bu, "scanf" bildirimi tarafından zorlanmamış olsa bile. – Shahbaz