为什么这个C++代码会让 SIGILL ideone.com



为什么会这样?该代码在Linux上的GCC 4.7和Windows上的MSVC++ 2010中有效并且不会生成警告。然而,在 ideone.com 它崩溃了 SIGILL .这里是否涉及未定义的行为?

#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"));
}

我在使用 GCC 4.4.6 时遇到错误:

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)

您不能通过 varargs 函数参数传递 struct 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()
{
    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

最新更新