AlexRayne 7 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба Привет! собираю в GCC7 такой вот С-код: printf("mode %d\n", (int)disconnect_mode() ); где `disconnect_mode()` - возвращает enum. компилятор ругается: warning: cast from function call of type 'DisconnectMode {aka enum DisconnectMode}' to non-matching type 'int' [-Wbad-function-cast] помогает только создать переменную временную, и ей из функции присваивать. посоветуйте как это можно обойти без кошмаров? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
heavyC1oud 0 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба 5 минут назад, AlexRayne сказал: собираю в GCC7 такой вот С-код: printf("mode %d\n", (int)disconnect_mode() ); printf("mode %i\n", (int)disconnect_mode() ); возможно так Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба 1 минуту назад, heavyC1oud сказал: printf("mode %i\n", (int)disconnect_mode() ); возможно так не канает использую в итоге все же кошмар: static inline int TOINT( int x){ return x;} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба 48 минут назад, AlexRayne сказал: где `disconnect_mode()` - возвращает enum. Покажите объявление disconnect_mode() и enum. Потому что по правилам языка C enum к int приводится неявно оно должно компилироваться даже без явного приведения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба 3 часа назад, Сергей Борщ сказал: Потому что по правилам языка C enum к int приводится неявно оно должно компилироваться даже без явного приведения. да приводится, если это не результат функции. курите Wbad-function-cast можно делать временную переменную int и в нее без кастов равнять. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба Ну, так скажем, покурил: $ cat tst.c #include <stdio.h> typedef enum my_awesome_enum_e { NO, YES, MAYBE, } my_awesome_enum_e; my_awesome_enum_e my_awesome_func( int i ); int main( void ) { printf( "value: %d\n", (int)my_awesome_func( 2 ) ); return 0; } my_awesome_enum_e my_awesome_func( int i ) { return (my_awesome_enum_e)i; } $ gcc -Wall -Wextra -pedantic tst.c $ ./a.out value: 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба 37 минут назад, AlexRayne сказал: да приводится, если это не результат функции. Можно какое-нибудь подтверждение ваших слов, например - цитату из страндарта? 37 минут назад, AlexRayne сказал: курите Wbad-function-cast Курите сами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 27 сентября, 2021 Опубликовано 27 сентября, 2021 (изменено) · Жалоба 20 минут назад, one_eight_seven сказал: Ну, так скажем, покурил: $ cat tst.c классна, а что за компилятор? а если явно задать опции -Wbad-function-cast , как оно скомпилит? у меня просто явно добавлена эта опция Изменено 27 сентября, 2021 пользователем AlexRayne Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба Простите, до этого не то отправил: #include <stdio.h> typedef enum my_awesome_enum_e { NO, YES, MAYBE, } my_awesome_enum_e; my_awesome_enum_e my_awesome_func( int i ); int main( void ) { printf( "value: %i\n", my_awesome_func( 17 ) ); return 0; } my_awesome_enum_e my_awesome_func( int i ) { return (my_awesome_enum_e)i; } $ gcc -Wall -Wextra -pedantic -Wbad-function-cast tst.c $ ./a.out value: 17 Just now, AlexRayne said: а если явно задать опции -Wbad-function-cast , как оно скомпилит? Да, скомпилит, но с warning'ом. Это я не то сначала отправил. Собирался отправить второй экземпляр, с вариантом, о котором писал @Сергей Борщ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба 2 минуты назад, one_eight_seven сказал: printf( "value: %i\n", my_awesome_func( 17 ) ); ну так вот еслиту не кастить - то все ок , ему нравится. а если явный каст в int поставить , то bad-function-cast заругает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба P.S. дело в том, что явное приведение, действительно, считается компилятором "плохим" если ему говорят так считать. Т.е. в тестах компилятора прямо есть тест на это - явное приведение енума к инту и наоборот - плохое. Я не копал глубоко, понял так, что enum в общем виде не обязан покрывать 2^32 значений, и будет отруган. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба 1 минуту назад, one_eight_seven сказал: явное приведение, действительно, считается компилятором "плохим" если ему говорят так считать. в нетах народ говорит что плохое явное приведение указателя void* к типу, и практика приведения (T*)malloc(...) типа приводит к ошибкам. и вроде как именно с этим кастом они и боролись. а енумы видимо зацепили паровозом. мой склероз давно потер - чем же это плохо. Но проблемы приведения результата функции к инту вообразить немогу. если у Вас есть пример - киньте? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба Ну, енум - это же совсем не инт. То, как он реализован в C - это одно, а назначение - это совсем другое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 67 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба "перечисление в целое" вполне безопасное преобразование, т.к. в целевом типе гарантировано есть возможность представления. Протому автоматическое преобразование должно работать без вопросов. А "целое в перечисление" - небезопасное, т.к. в перечислении просто может не оказаться соответствующего значения. И тут требуется явное преобразование, т.е. ответственность перекладывается на программиста. То, что компилятор ругается при включенном предупреждении, имеет к вышесказанному опосредованное отношение - верно заметили, что если компилятору велено ругаться на такой код, он будет ругаться - делает, что велят. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба 2 часа назад, dxp сказал: А "целое в перечисление" - небезопасное, т.к. в перечислении просто может не оказаться соответствующего значения. И тут требуется явное преобразование, т.е. ответственность перекладывается на программиста. В плюсах. В обычных же сях такое неявное преобразование разрешено. 2 часа назад, dxp сказал: То, что компилятор ругается при включенном предупреждении, имеет к вышесказанному опосредованное отношение Причем это предупреждение работает только в сях и объективных сях. Вот тут достаточно внятно написано - зачем это предупреждение и с какими именно проблемами кода оно должно помогать бороться. А именно - с явными приведениями типов в тех местах, где такое приведение не требуется ввиду наличия неявного приведения и ввиду наличия в сях до стандарта 11 года возможности использовать функцию без предварительного объявления, которую компилятор обязан считать возвращающей int. Однако, в таком случае выдается предупреждение об использовании функции без прототипа, которого достаточно для выявления подобных недоработок кода, так что смысла дополнительно включать еще и это предупреждение (а оно может быть включено только принудительно) не видно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться