# ф-ция, возвращающая указатель на ф-цию и MS VC

Тема в разделе "WASM.HEAP", создана пользователем kaspersky, 5 июн 2008.

  1. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    есть код следующего вида:

    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

    очень хочется побороть это предупреждение, т.к. в текущем проекте все предупреждения компилятора приравниваются к ошибке (ну бзэк у манегера такой).
    кстати, багдад даже со всеми включенными варнингами молчит и не видит здесь ничего неправильного... так что код правильный или я ничего не понимаю в сях.
     
  2. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Может перед нулем в return 0; втавить тип возращаемого значения?
     
  3. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    PROFi
    не, он ругается именно на return foo
    грит, что она не в списке аргументов...
    не, ну конечно можно переписать код как:

    void (*xxx)(char*); xxx = foo;
    if (a) return xxx; else return 0;

    но это же маразмы крепчают ;(
    хотя ругательство исчезает...
     
  4. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Да хрен редьки не слаще.

    Вообще у MS всегда были проблемы с возвращением указателей на функцию.

    Код (Text):
    1. void (*xxx)(char*); xxx = foo;
    2. if (a) return xxx; else    return 0;
    Это во что ассемблируется MS и есть ли разница с if (a) return foo; else return 0;?
     
  5. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    > Это во что ассемблируется 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 даже свои либы скомпилить в таком случае оказывается не в состоянии...
     
  6. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Дык в Си для получения адреса чего бы то ни было используется оператор &.
    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: }
    нормально компилится.
     
  7. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    diamond
    > Дык в Си для получения адреса чего бы то ни было используется оператор &.
    > нормально компилится.
    хм. действительно. спасибо за совет!!! с меня пиво, вобла и бабы ;)
    наверно надо завязывать мне стандарт читать, где сказано, что
    foo и &foo равнозначны и взаимозаменяемы.
     
  8. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    kaspersky

    ms vc 6 далека от соответствия стандарту, это вроде ни для кого не новость.
     
  9. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    kaspersky

    Не равнозначны, а одно умеет decay в другое.
     
  10. Gang_offset

    Gang_offset New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2006
    Сообщения:
    3
    Код (Text):
    1. #pragma warning( disable : 4550)
    и нет проблем )
     
  11. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    _DEN_
    Что это ещё такое?
     
  12. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Если компилировать в режиме C++, то варнинга нет в обоих вариантах.
     
  13. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    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, а потом откастил.
     
  14. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    kaspersky
    Код (Text):
    1. void foo(char *s){ printf(s); }
    2.  
    3. typedef void (*pfoo_t)(char *s);
    4. pfoo_t foo_p(int a)
    5. {
    6.    if (a) return (pfoo_t)foo; else    return 0;
    7. }
     
  15. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    green
    йееесъ!!! работает!!!!
    правда непонятно почему...
    кстати, можно и без typedef, достаточно кастинга перед foo....
    неее... ms точно что-то чудит...
     
  16. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    kaspersky
    Более свежие msvc (по крайней мере 8 и 9) компилят без ворнинга.
     
  17. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    у меня последняя студия стоит на виртуалке, а так работаю на ms vc 6,
    нда... надо было проверить скомпилировать на последней, прежде чем сюда постить...
     
  18. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    kaspersky
    Можно ставить сразу несколько студий. У меня мирно уживаются 6, 8 и 9.
     
  19. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Только в режиме С++. Переименуй файлик в .с и попробуй ещё раз.
     
  20. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    green
    > Можно ставить сразу несколько студий. У меня мирно уживаются 6, 8 и 9.
    можно, но как-то не особенно нужно (во всяком случае мне),
    поставил Express только чтобы знать, что там за грабли,
    на которые быстро наступил, не сумев откомилить плагин x86emu для иды,
    т.к. в Express'е нет MFC, а x86emu юзает afx, который, впрочем, нашелся в gnu-версии ;)
    я же IDE все равно не использую, оптимизатор там сильно не улучшен (беглое сравнение с шестеркой не выявило существенных продвижек), так что смысла в ней (для меня) нету. ну разве что C# потеразать. сейчас как раз я участвую в разработке дебагера, дебажащего смесь управляемого байт-кода и неуправляемого машинного кода без использования NET'а и хотя я совсем не кодер (моя задача - выявление недокументированных фич NET'а, не попавших в стандарт на байт-код, плюс исследование механизмов взаимодействия управляемого и неуправляемого кода, т.е. чистый реверс, а для этого достаточно иды на основной машине ;)