2012-10-02 25 views
7

Son versiyonları olmadan deyimi hatasız aşağıdaki programı derleme eğer:İşlev çağrı parantez Fedora Linux üzerinde gcc ve clang ait

#include <ctype.h> 
#include <stdio.h> 

int main(int argc, char *argv[]) { 
    char c = 'a'; 
    if islower(c) 
     printf("%d", c); 
    else 
     printf("%c", c); 
    return 0; 
} 

Bu gcc 4.7.2 ve clang 3.0 ile olduğunu. Mac'imde, aksine, hem gcc 4.2.1 hem de Apple clang 4.1, beklendiği gibi "islower (c)" satırında eksik parantezlerden şikayetçidir. Her durumda, derleyicileri "-std = c99" ile çalıştırdım.

Bu, gcc ve clang'ın son sürümlerinde bir hata mı, C dilinde bir tuhaflık mı yoksa başka bir şey mi? C99 standardı (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf s. 133), tüm durumlarda ifadeler varsa parantezleri yetkilendiriyor gibi görünmektedir.

+0

Eğer 42 printf ("42! \ N"); 'ise derlenecek mi? Varsa, ifadeler üzerinde ilgi çekici bir şeydir. Formal olarak, eğer 'if', '42' ve '(42) 'unu unutursak, aynıdır. Islower (c) 've' (islower (c)) 'ile ditto. –

+0

Alexey, bu oldukça doğru değil, çünkü C dilbilgisi bu özel bağlamda parantez gerektirir. Sadece parantezlerin burada bir makro tarafından sağlandığı gibi oluyor. –

+0

Jelle, bu yüzden “ifadelerin ilginç bir şekilde alınması” dedim çünkü bildiğim kadarıyla, parenslerin gerekli olduğu bilgisini aldım. –

cevap

10

Sadece /usr/include/ctype.h bulunan ctype.h dosyası üzerinden baktı ve islower için şu tanımı bulundu: Ben bulmak __isctype() için

#define islower(c) __isctype((c), _ISlower) 

tanımına gitmek:

#define __isctype(c, type) \ 
    ((*__ctype_b_loc())[(int) (c)] & (unsigned short int) type) 

Yani kod if islower(c) Genişlediğinde için:

if ((*__ctype_b_loc())[(int) (c)] & (unsigned short int) _ISlower) 

Söylendiği gibi, genişletme sırasında parantezi ekledi.

+0

gevşeyin ve haklısınız, teşekkürler! Durumun böyle olduğunu tahmin etmeliydim. gcc -E, "((* __ ctype_b_loc()) [(int) ((m))] & (imzasız kısa int) _ISalpha)" dediğiniz gibi. –

13

Muhtemelen islower() bir makrodur ve genişletme parantezi ekler.

Önceden işlenmiş çıktıyı, -E seçeneği ile derleyerek alabileceğiniz GCC'den gönderin.