LINUX.ORG.RU

C, void, printf


0

0

Увидел такой вот "хак"? Вызов printf("Hello, world!\n") оформлен, как (void) printf("Hello, world\n"). Т.е. добавили (void) перед фукнцией, с которой не забирают выходного значения. Также вопрос по препроцессору - сейчас модно делать #define MAX 100 или лучше сделать enum {MAX=100}. Т.е. вообще отделяться от препроцессора.


Вопрос собственно - это верно с точки зрения нормального оформления кода?

arsss
() автор топика
Ответ на: комментарий от lester

В том то и дело, что есть человек (утверждает, что гуру в программировании) и этот (void) является именно Тру методом. Тоже самое и про препроцессор.

arsss
() автор топика
Ответ на: комментарий от arsss

> утверждает, что гуру в программировании

"Убивать надо таких знатоков!" (с)

lester ★★★★
()

>int printf ( const char * format, ... );

>any value can be cast to void

такой костыль (приведение к void) позволяется избавиться от предупреждения о проигнорированном возвращаемом значении (ну или явно указать, что оно игнорируется)

>Также вопрос по препроцессору

если язык - C, то #define тебе в руки

jtootf ★★★★★
()
Ответ на: комментарий от lester

> (void) здесь просто лишний, а никакой не "хак"

Если включить в gcc -Wunused-value, то он будет выдавать предупреждение, если функция что-то возвращает, но возвращаемое значение не используется. Также предупреждения выдают разные анализаторы кода вроде splint.

Думаю что существует мало ситуаций, когда реально можно игнорировать возвращаемое значение. Во многих случаях это просто ошибка. Так что включить соответствующий варнинг и в особых случаях приводить к void может быть полезным.

P.S. На правах ИМХО.

Deleted
()

В сях - не имеет смысла. И не может его иметь.

В плюсах - ну, если используется за каким-то хреном нестандартный printf, возвращающий не int, а какой-то класс, и для этого класса перегружено преобразование в void... то за такое нужно вешать на ближайшем фонаре.

Miguel ★★★★★
()
Ответ на: комментарий от Deleted

> Если включить в gcc -Wunused-value, то он будет выдавать предупреждение, если функция что-то возвращает, но возвращаемое значение не используется.

вы не правы, gcc выдает предупреждения об неиспользуемых x и k, про результат возвращаемый функцией он молчит даже при -Wall:

int A( int x )
{
int k = 1;
return 1;
}

void B( void )
{
A();
}

lester ★★★★
()

Тулзы типа coverity ругаются иногда на непроверяемые значения функций. Но все зависит как в этой тулзе функция описанна. Например, если возвращаемое значение malloc теряется, то это явно проблема. И есть компании где код принудительно прогоняется через coverity, и если оно ругается то это вызывает вопросы. Поэтому всякие индусы ставят такие затыки (хотя я считаю что это в корне непраильно, как бездумное следование таким тулзам, так и бездумная вставка затычек).

В использовании препроцессора в С нет ничего предосудительного, нужно только знать как он работает, где он оправдан, а где нет.

imp ★★
()
Ответ на: комментарий от alexru

> Но есть lint, который ругается если возвращаемое значение не используется.

не аргумент - многие функции возвращают значения( тот же printf, strcpy etc. ), которые нужны очень редко, коверкать из-за этого код( причем не под компилятор - что можно понять, а под тулзу ) по-моему не лучший вариант

lester ★★★★
()
Ответ на: комментарий от lester

Согласен. Но наиболее распространеное объяснение именно такое. Тем более, что оно там отключается.

alexru ★★★★
()
Ответ на: комментарий от alexru

>Хотя говорят в OpenBSD весь код такой и живут :)

равно как и в практически любом другом reliability-ориентированном проекте, пишушемся на языке, допускающем ошибки игнорирования возвращаемых значений

когда линтование - обязательный этап QA, а соглашения о кодировании жёстче, чем у проектировщиков стандартной библиотеки языка

jtootf ★★★★★
()
Ответ на: комментарий от alexru

> Для одного значения enum - это просто глупо. Для двух и более лично мне больше нравится enum.

Для одиночных значений нужно использовать что-то типа const int m = 100 :-)

smh ★★★
()
Ответ на: комментарий от Miguel

> В сях - не имеет смысла. И не может его иметь.

Мигель, когда (вместо разговоров в детсаде) ты расскажешь тот пример с virtual template? А то твои комбинаторы мне не осилить, а пример интересен.

www_linux_org_ru ★★★★★
()

На "детсад" всем остальным просьба не обижатся. Смысл в том, что Мигель знает интересный флеймообразующий вопрос, и молчит уже сколько времени, как партизан на допросе :-)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от lester

> вы не правы, gcc выдает предупреждения об неиспользуемых x и k, про результат возвращаемый функцией он молчит даже при -Wall:

Действительно, ошибся.

Deleted
()
Ответ на: комментарий от www_linux_org_ru

Вероятно, никогда. Перестал интересоваться.

Miguel ★★★★★
()
Ответ на: комментарий от arsss

> утверждает, что гуру в программировании

Если увидишь на дороге монаха из Шао-Линь -- ударь его. Если это настоящий монах из Шао-Линь, у тебя не получится ударить его. Если получилось -- это притворщик, так ему и надо.

Пусть этот гура объяснит, нахуа там (void), и в чём его Ъ. Не сможет -- он не гура. Ударь его.

one_more_hokum ★★★
()
Ответ на: комментарий от jtootf

> такой костыль (приведение к void) позволяется избавиться от предупреждения о проигнорированном возвращаемом значении

Первый раз такое слышу. Что сделать, чтоб увидеть это предупреждение?

one_more_hokum ★★★
()

А возвращаемое функцией значение куда заностися? в стэк или регистр и всегда ли оно сохраняется?

dimon555 ★★★★★
()
Ответ на: комментарий от Deleted

Интересно, и почему я решил, что у компилятора есть опция, которая включает предупреждение при неиспользованном результате? Загадка. Но в поисках ответа я наткнулся на это:

http://gcc.gnu.org/onlinedocs/gcc/Non_002dbugs.html

> 10.9 Certain Changes We Don't Want to Make

> Warning when a non-void function value is ignored.

> C contains many standard functions that return a value that most programs choose to ignore. One obvious example is printf. Warning about this practice only leads the defensive programmer to clutter programs with dozens of casts to void. Such casts are required so frequently that they become visual noise. Writing those casts becomes so automatic that they no longer convey useful information about the intentions of the programmer. For functions where the return value should never be ignored, use the warn_unused_result function attribute (see Function Attributes).

Deleted
()
Ответ на: комментарий от one_more_hokum

>Первый раз такое слышу. Что сделать, чтоб увидеть это предупреждение?

отлинтовать приложение, например

jtootf ★★★★★
()
Ответ на: комментарий от Deleted

> Интересно, и почему я решил, что у компилятора есть опция, которая включает предупреждение при неиспользованном результате? Загадка.

Ну, в каком-то смысле есть:

int fn() __attribute__((warn_unused_result));

А использовать явное приведение результата выполнения функции к void, по большому счёту, только загромождает код. Разумнее как раз таким образом объявить нужные функции, где такое игнорирование действительно приводит к проблемам. Увы, gcc-specific. 8((

kemm
()
Ответ на: комментарий от lester

>даже встроенный в vs2008 анализатор более вменяемый

если под вменяемостью подразумевать толерантность к error-prone конструкциям - то да, несомненно

jtootf ★★★★★
()
Ответ на: комментарий от kemm

>явное приведение результата выполнения функции к void, по большому счёту, только загромождает код

на то он и костыль

>Разумнее как раз таким образом объявить нужные функции, где такое игнорирование действительно приводит к проблемам

да

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

> если под вменяемостью подразумевать толерантность к error-prone конструкциям - то да, несомненно

ну да, если не дописать (void) перед strcpy - произойдет нечто страшное :)

lester ★★★★
()
Ответ на: комментарий от lester

>ну да, если не дописать (void) перед strcpy - произойдет нечто страшное :)

ты знал! ты знал!

jtootf ★★★★★
()
Ответ на: комментарий от one_more_hokum

> Если увидишь на дороге монаха из Шао-Линь -- ударь его. Если это настоящий монах из Шао-Линь, у тебя не получится ударить его. Если получилось -- это притворщик, так ему и надо.

А если это ученик - он будет благодарен тебе за урок.

Miguel ★★★★★
()

(void)printf("Hello, world\n") - стиль который обычно юзают виндовые программисты. VS кидается варнингами.

По поводу enum'а. Если бы ты писал в C++, то однозначно enum или const. В сях по барабану. Да и const в сях всегда вычисляется на этапе выполнения.

А вообще, лучше стараться меньше юзать препроцессор. enum значения gdb умеет показывать, а вот дефайны в gdb будут показываться магическими числами.

badgopher
()
Ответ на: комментарий от badgopher

>(void)printf("Hello, world\n") - стиль который обычно юзают виндовые программисты.

И не только.
Для embedded system возможно отлючение резервирования регистров компилятором для возвращяемых значений встроенной реализации printf.

elipse ★★★
()
Ответ на: комментарий от badgopher

> А вообще, лучше стараться меньше юзать препроцессор. enum значения gdb умеет показывать, а вот дефайны в gdb будут показываться магическими числами.

Неправда ваша.

info gdb:

GDB knows about preprocessor macros and can show you their expansion (*note Macros::). Most compilers do not include information about preprocessor macros in the debugging information if you specify the `-g' flag alone, because this information is rather large. Version 3.1 and later of GCC, the GNU C compiler, provides macro information if you specify the options `-gdwarf-2' and `-g3'; the former option requests debugging information in the Dwarf 2 format, and the latter requests "extra information". In the future, we hope to find more compact ways to represent macro information, so that it can be included with `-g' alone.

Хотя размер бинаря раздувает эпически. 8))

kemm
()
Ответ на: комментарий от kemm

Не знал :-)) Всегда использовал -g :-) Надо переходить на -g3 :-))))

badgopher
()
Ответ на: комментарий от badgopher

> В сях по барабану. Да и const в сях всегда вычисляется на этапе выполнения.

ну да :))

#define MAX 100
#define MAX 101
#define MAX 102

если так - будет только предупреждение

enum {MAX2=100};
enum {MAX2=101};

тут уже будет останов по ошибке

elipse ★★★
()
Ответ на: комментарий от kemm

> А какая разница? Один фиг код должен без предупреждений собираться. 8))

реально пакеты давно в дистрах собирали ?

elipse ★★★
()
Ответ на: комментарий от elipse

ну да :-) и поэтому препроцессор и надо юзать по минимуму. А вообще, игнорирование варнингов со стороны программиста никогда ни к чему хорошему не приводило :-)

badgopher
()
Ответ на: комментарий от badgopher

> ну да :-) и поэтому препроцессор и надо юзать по минимуму. А вообще, игнорирование варнингов со стороны программиста никогда ни к чему хорошему не приводило :-)

А заклинания и я могу толкать хорошо.

elipse ★★★
()
Ответ на: комментарий от elipse

> реально пакеты давно в дистрах собирали ?

К сожалению, многие руководствуются принципом: главное чтобы работало. Отсюда и большинство багов в коде. Компилятор нам кричит о помощи, а мы ему: "Заткнись зараза! И без тебя тошно" :-)

badgopher
()
Ответ на: комментарий от elipse

Наличие массы говнокода не повод говорить, что предупреждения должны игнорироваться. Если уж мы обсуждаем, как _правильно_ писать, то правильно написанное обязано собираться без предупреждений с -Wall как минимум.

kemm
()
Ответ на: комментарий от elipse

> А заклинания и я могу толкать хорошо.

А вдруг поможет?! Человек призадумается и станет лучше писать код :-)

badgopher
()
Ответ на: комментарий от kemm

> Наличие массы говнокода не повод говорить, что предупреждения должны игнорироваться.

собери тогда glibc - прдупреждений вагон и малая тележка
если , я хочу изолировать и сделать уникальным определение в #define сonst
- тогда это хороший способ (дать в лоб умникам-торопыгам упрощенцам) как определить константу в enum .

elipse ★★★
()
Ответ на: комментарий от elipse

>> Наличие массы говнокода не повод говорить, что предупреждения должны игнорироваться. > собери тогда glibc - прдупреждений вагон и малая тележка

Наличие массы говнокода не повод говорить, что предупреждения должны игнорироваться.

> если , я хочу изолировать и сделать уникальным определение в #define сonst - тогда это хороший способ (дать в лоб умникам-торопыгам упрощенцам) как определить константу в enum .

Эмн... Мой парсер русского языка на этом сломался. 8))

kemm
()
Ответ на: комментарий от kemm

> Наличие массы говнокода не повод говорить, что предупреждения должны игнорироваться.

автору подобных писаний парсер уже излишен :)

elipse ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.