есть код следующего вида: 1: void foo(char *s){ printf(s); } 2: 3: void (*foo_p(int a)) (char*) 4: { 5: if (a) return foo; else return 0; 6: } при компиляции ms vc 6 выдает следующее: test.c(5) : warning C4550: expression evaluates to a function which is missing an argument list очень хочется побороть это предупреждение, т.к. в текущем проекте все предупреждения компилятора приравниваются к ошибке (ну бзэк у манегера такой). кстати, багдад даже со всеми включенными варнингами молчит и не видит здесь ничего неправильного... так что код правильный или я ничего не понимаю в сях.
PROFi не, он ругается именно на return foo грит, что она не в списке аргументов... не, ну конечно можно переписать код как: void (*xxx)(char*); xxx = foo; if (a) return xxx; else return 0; но это же маразмы крепчают ;( хотя ругательство исчезает...
Да хрен редьки не слаще. Вообще у MS всегда были проблемы с возвращением указателей на функцию. Код (Text): void (*xxx)(char*); xxx = foo; if (a) return xxx; else return 0; Это во что ассемблируется MS и есть ли разница с if (a) return foo; else return 0;?
> Это во что ассемблируется MS если без оптимизации, то: mov [ebp+var_4], offset _foo cmp [ebp+arg_0], 0 jz short loc_27 mov eax, [ebp+var_4] jmp short loc_29 loc_27: xor eax, eax loc_29: > и есть ли разница с if (a) return foo; else return 0;? после оптимизации в обоих случаях мы получаем: mov eax, [esp+arg_0] neg eax sbb eax, eax and eax, offset _foo retn > Вообще у MS всегда были проблемы с возвращением указателей на функцию. угу, вот я сейчас с ними и столкнулся... сейчас пишу манегеру письмо, пытаясь объяснить, что ms козлина и лишнаяя временная переменная код не украшает, а только захламляет его (тем более, что в реальном коде функа может возвращать указатель на разные функции, и если на каждую из них заводить по переменной, это не вариант вообще...) и откуда только взялась тенденция приравнивать предупреждения компилятора к ошибкам?! тем более, что ms vc даже свои либы скомпилить в таком случае оказывается не в состоянии...
Дык в Си для получения адреса чего бы то ни было используется оператор &. 1: void foo(char *s){ printf(s); } 2: 3: void (*foo_p(int a)) (char*) 4: { 5: if (a) return &foo; else return 0; 6: } нормально компилится.
diamond > Дык в Си для получения адреса чего бы то ни было используется оператор &. > нормально компилится. хм. действительно. спасибо за совет!!! с меня пиво, вобла и бабы наверно надо завязывать мне стандарт читать, где сказано, что foo и &foo равнозначны и взаимозаменяемы.
reverser > Если компилировать в режиме C++, то варнинга нет в обоих вариантах. компилится приходится в си, отсюда и траблы. _DEN_ > Не равнозначны, а одно умеет decay в другое. ну это понятно т.к. есть разница между void foo(char*); и void (*xxx)(char*) = foo; &foo и foo - указатель на foo, xxx - указатель на foo &xxx - указатель на xxx, указывающую на foo сейчас обнаружил, что в проекте часть фунок уже представляет собой указатели на функции и потому решение от diamond'а не прокатывает, увы ;(( Gang_offset > pragma warning( disable : 4550) > и нет проблем ) это не решение проблемы... т.к. код должен быть системно независим. если бы не это требование, я бы вообще не мучался особо, а вернул DWORD, а потом откастил.
kaspersky Код (Text): void foo(char *s){ printf(s); } typedef void (*pfoo_t)(char *s); pfoo_t foo_p(int a) { if (a) return (pfoo_t)foo; else return 0; }
green йееесъ!!! работает!!!! правда непонятно почему... кстати, можно и без typedef, достаточно кастинга перед foo.... неее... ms точно что-то чудит...
у меня последняя студия стоит на виртуалке, а так работаю на ms vc 6, нда... надо было проверить скомпилировать на последней, прежде чем сюда постить...
green > Можно ставить сразу несколько студий. У меня мирно уживаются 6, 8 и 9. можно, но как-то не особенно нужно (во всяком случае мне), поставил Express только чтобы знать, что там за грабли, на которые быстро наступил, не сумев откомилить плагин x86emu для иды, т.к. в Express'е нет MFC, а x86emu юзает afx, который, впрочем, нашелся в gnu-версии я же IDE все равно не использую, оптимизатор там сильно не улучшен (беглое сравнение с шестеркой не выявило существенных продвижек), так что смысла в ней (для меня) нету. ну разве что C# потеразать. сейчас как раз я участвую в разработке дебагера, дебажащего смесь управляемого байт-кода и неуправляемого машинного кода без использования NET'а и хотя я совсем не кодер (моя задача - выявление недокументированных фич NET'а, не попавших в стандарт на байт-код, плюс исследование механизмов взаимодействия управляемого и неуправляемого кода, т.е. чистый реверс, а для этого достаточно иды на основной машине