2012-01-03 2 views
-1

У меня есть код.Почему этот код компилируется?

class A 
{ 
public: 
    int foo(int i) 
    { 
     return i; 
    } 
}; 

int foo(int i) 
{ 
    return i; 
} 

int (A::*ptrFoo)(int) = NULL; 
int (*_foo)(int) = NULL; 

int main() 
{ 
    ptrFoo = &A::foo; 
    _foo = foo; 

    (*_foo)++++++++++++++(10); //This dont compile... 

    A a; 
    (a.*ptrFoo)+++++++++++++++++(10); //This compiles ???? 

} 

, пожалуйста, скажите мне, что это такое ?? неопределенное поведение или что? Я скомпилировал его в VS2008. Непосредственно последняя строка кода успешно компилируется.

+2

'++++++++++++++' - это семь с половиной операторов после инкремента. Предположительно, компилятор попадает на половину. –

+0

Вы скомпилировали его как C и C++? Или почему вы включили оба тега? –

+0

Я скомпилировал его в C++ (VS2008) .i удалит тег «C» – YAHOOOOO

ответ

2

Ни одно выражение не должно компилироваться: в C++ вы не можете выполнять арифметику на указателе на функцию или функцию-член, а также на тип функции или функцию-член. Два выражения в вашей программе пытаются выполнить арифметику для функции и для функции-члена соответственно.

Если ваш компилятор принимает второе выражение, это связано с ошибкой в ​​компиляторе.

1

Прежде всего заметим, что указатель на функции различны с указатель функций членов.

Ваш первый пример - указатель на обычную функцию. Он содержит реальный адрес памяти функции. Когда вы разыгрываете его ((*_foo)), вы сами получаете функцию, а арифметические операции, включая ++ на функцию (указатель функции), бессмысленны.

Второй - это еще одна история, указатели на функции-члены классов не несут адрес функции в памяти. Фактически, как компилятор управляет функциями-членами, зависит от реализации. Указатель на функцию-член может содержать какой-либо адрес или, возможно, некоторую информацию, относящуюся к компилятору. Арифметика по этому типу также бессмысленна.

Поэтому мы не знаем, что такое значение (a.*ptrFoo), но в вашем случае MSVC2008 удалось его компилятор либо из-за ошибки, либо по дизайну.

Кстати, GCC не компилирует ни одно из двух утверждений и не допускает ошибок на обоих.

Вышеупомянутое верно, если вы положили даже число + или нечетных чисел; мы все равно делаем арифметику. (Если есть нечетное число +, тогда нет вызова функции, так как в вашем втором примере вы увеличиваете функцию 8 раз, а последний оставшийся + добавляет к результату 10. При этом это не имеет значения: мы пытаются изменить указатель функции/функции функции.)

+0

«Как компилятор управляет функциями-членами, зависит от реализации» Реализация функций, не являющихся членами, также является детализацией реализации. –

+0

@JamesMcNellis: Вы правы, но каждая обычная функция имеет явный адрес в памяти, нет? Но «адрес» функции-члена не является тем, что мы знаем; каждый компилятор имеет свои собственные парадигмы по реализации классов. – Hossein

Смежные вопросы