2012-07-04 32 views
5

Neden oluyor? Kod, Linux'ta GCC 4.7 ve Windows'ta MSVC++ 2010 ile hiçbir uyarı üretmez ve üretmez. Ancak, ideone.com'da SIGILL ile crashes. Tanımlanmamış davranış burada yer alıyor mu?Bu C++ kodu neden ideone.com'da SIGILL oluyor?

#include <iostream> 
#include <cstdarg> 

using namespace std; 

enum types 
{ 
    INT, 
    DOUBLE, 
    CHAR, 
    STRING 
}; 

struct mt 
{ 
    types type; 

    union 
    { 
     int   i; 
     double  d; 
     char  c; 
     const char *s; 
    } val; 

    mt(int i) 
     : type(INT) 
    { 
     val.i = i; 
    } 

    mt(double d) 
     : type(DOUBLE) 
    { 
     val.d = d; 
    } 

    mt(char c) 
     : type(CHAR) 
    { 
     val.c = c; 
    } 

    mt(const char *s) 
     : type(STRING) 
    { 
     val.s = s; 
    } 
}; 

void print(int n, ...) 
{ 
    va_list ap; 

    va_start(ap, n); 

    for (int i = 0; i < n; i++) 
    { 
     mt x(va_arg(ap, mt)); 

     switch (x.type) 
     { 
     case INT: 
      cout << x.val.i << endl; 
      break; 
     case DOUBLE: 
      cout << x.val.d << endl; 
      break; 
     case CHAR: 
      cout << x.val.c << endl; 
      break; 
     case STRING: 
      cout << x.val.s << endl; 
      break; 
     } 
    } 

    va_end(ap); 
} 

int main() 
{ 
    print(4, mt(2), mt(4.2), mt('a'), mt("Hello")); 
} 

cevap

1

Ben GCC 4.4.6 hataları var: işlev parametreleri varargs aracılığıyla Sen struct s geçemez

test.cpp: In function ‘void print(int, ...)’: 
test.cpp:59: warning: cannot receive objects of non-POD type ‘struct mt’ through ‘...’; call will abort at runtime 
test.cpp: In function ‘int main()’: 
test.cpp:83: warning: cannot pass objects of non-POD type ‘struct mt’ through ‘...’; call will abort at runtime 
test.cpp:83: warning: cannot pass objects of non-POD type ‘struct mt’ through ‘...’; call will abort at runtime 
test.cpp:83: warning: cannot pass objects of non-POD type ‘struct mt’ through ‘...’; call will abort at runtime 
test.cpp:83: warning: cannot pass objects of non-POD type ‘struct mt’ through ‘...’; call will abort at runtime 
$ g++ --version 
g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3) 

yerine geçmesi işaretçiler: sistemimde çalışıyor

void print(int n, ...) 
{ 
    va_list ap; 

    va_start(ap, n); 

    for (int i = 0; i < n; i++) 
    { 
     mt *x(va_arg(ap, mt *)); 

     switch (x->type) 
     { 
     case INT: 
      cout << x->val.i << endl; 
      break; 
     case DOUBLE: 
      cout << x->val.d << endl; 
      break; 
     case CHAR: 
      cout << x->val.c << endl; 
      break; 
     case STRING: 
      cout << x->val.s << endl; 
      break; 
     } 
    } 

    va_end(ap); 
} 

int main() 
{ 
    mt mt1(2); 
    mt mt2(4.2); 
    mt mt3('a'); 
    mt mt4("Hello"); 
    print(4, &mt1, &mt2, &mt3, &mt4); 
} 

:

$ ./a.out 
2 
4.2 
a 
Hello 
+0

POD olan herşeyi geçebileceğini düşündüm (bkz. C++ 03, 5.2.2.7, "_or class type_"). Ve 'yapı mt' POD'u bana gösteriyor, çünkü (a) POD olmayan üyelere sahip değil, (b) kullanıcı tanımlı bir kopya atama operatörüne sahip değil ve (c) bir kullanıcısı yok tanımlanmış yıkıcı (Madde 9'a bakınız). Bu kesinti yanlış mı? –

+0

@AndreyVihrov Varargs bir korsanlıktan başka bir şey değildir ve (taşınabilirken) taşınabilir değildir. Yöntemler arasında nesneleri geçirmek için 'std :: ' veya başka bir koleksiyon sınıfını kullanın. – trojanfoe

+2

Katılmıyorum. Varargs portatiftir, çünkü bunlar resmi olarak hem C hem de C++ standartlarının bir parçasıdırlar :-) –

İlgili konular