2012-06-27 5 views
4

Что делает размещение void; на линии делать в C? Компилятор предупреждает об этом, но я не понимаю. Какой смысл в том, чтобы вносить пустоту в такую ​​строку?Что делает оператор void в C?

#include <stdio.h> 

int main() { 
     void; 
     printf("word dude"); 
     return 1; 
} 

да

$ gcc -pedantic -ansi -Wall -Wextra eh.c -o eh 
eh.c: In function 'main': 
eh.c:4:2: warning: useless type name in empty declaration 
$ ./eh 
word dude 

Люди, кажется, путаясь, что я спрашиваю: Что это значит линия, она делает что-нибудь? почему это действительно?

void; 

Удалены недействительным бросок, как это вызывает ненужную дискуссию.

+1

компилятор говорит вам, что вы сделали, это бесполезно. Так в чем же вопрос? –

+4

Реальный вопрос: почему это не синтаксическая ошибка? – kay

+1

@Oil: вопрос в том, почему это компилируется и что это значит. – megazord

ответ

2

Этот вопрос меня интересует, потому что моя первая мысль была K & Р. Я вернулся к своему старому K & R книги (Приложение A стр.192) на найденной аннотации о декларациях (Transcripted):

 
8. Declarations 

Declarations are used to specify the interpretation which C gives to each identifier; they do not necessarily reserve storage associated with the identifier. Declarations have 
the form 
    declaration: 
     decl-specifier declarator-listopt; 

The declarators in the declarator-list contain the identifiers being declared. The decl-specifiers consist of a sequence of type and storage class specifiers. 
    decl-specifiers: 
     type-specifier decl-specifiersopt 
     sc-specifier decl-specifiersopt 

Это заставляет меня думать, что списки делараторов являются необязательными (это означает, что он может быть пустым).

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

В моей узкой интерпретации, что это может быть еще законно (но устаревшие) С.

+0

это не отвечает на вопрос – Thomas

+0

Ну, ИМО нет четкого ответа. В течение долгого времени K & R _was_ ссылался на стандартизацию ANSI C. ANSI C является надмножеством K & R, поэтому множество странностей K & R наследуется. Конечно, это может быть не полным, я думаю, что лучший ответ на вопрос «почему этот действительный» вопрос «потому что K & R сказал так». –

1
void; 

Нет смысла делать это, он ничего не делает.

Вы получили это из книги? Должно быть, ошибка.

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

Update:

Похоже, вы добавили еще одну строку :

(void)printf("word dude"); 

это - в отличие от предыдущего void; - говорит компилятору Явно игнорировать возвращаемое значение printf() функция (количество напечатанных символов) и предупреждать сообщения о придирчивой/педантичной настройке на компиляторе или других инструментах, например lint, чтобы перестать жаловаться.

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

+4

Я знаю, что lol я набрал 1, потому что я ел, и было легче ударить – megazord

+0

@megazord ха-ха .. лучший разум когда-либо :) .. и это на самом деле не влияет на этот пример. – Levon

+0

@megazord Я видел, что вы добавили еще одну строку с 'void printf (..)' .. Я обновил свой ответ, чтобы включить его. – Levon

0

Он печатает ту же ошибку, если вы меняете void с int или любым другим типом.

void - это тип и он ожидает чего-то после этого типа. Это не имеет никакого смысла, поскольку записывает только int без имени переменной (или функции) после него.

0

void используется как тип данных на C, и я подумал об этом, я никогда не слышал об эквивалентности языка ассемблера NOP в C, поэтому наличие пустоты на линии, вероятно, является ошибкой.

+1

Я не спрашиваю, что такое пустота, я спрашиваю, что значит просто иметь линию, которая говорит «пустота»; – megazord

+0

Ответ отредактирован за ваш комментарий. – octopusgrabbus

2
 void;      // 1 
     (void)printf("word dude"); // 2 

Первое утверждение является недействительным заявление: это не C.

Во втором заявлении (void) бросок делает ваше намерение ясно отказаться от возвращаемого значения. Еще одно распространенное применение - заставить замолчать некоторые инструменты статического анализа, такие как Lint.

0

Вы уверены, что это точный/стенографический текст?

Линия:

int main() { 

Если вероятно

int main(void) { 

Это означает, что ваша программа не принимает аргументы командной строки (например: если ваша окончательная программа называется out.exe, вы можете» t передать аргументы, например out.exe -a -c и т. д.).

Кроме того, вы можете void-cast сообщить вашему компилятору, что вы намеренно игнорируете вывод функции. Хорошим примером является функция ведения журнала.

например:

int log(int val) { 
    printf("Value is %d \n"); 
    if (val < 0) { 
    printf("Value is negative; error!\n"); 
    return -1; 
    } else { 
    printf("Value is non-negative; Probably not an error!\n"); 
    return 0; 
    } 
} 

Если вы просто хотите, чтобы вызвать эту функцию, так что делает вещи Е(), вы должны назвать его так: (void)log(some_int_variable). Это говорит компилятору, что вас не волнует результат. Если вы назовете это так: log(some_int_variable) ваш компилятор (наряду с другими инструментами анализа кода, такими как PC_LINT) выкинет предупреждения, так как вы не используете возвращаемое значение функции и ожидаете присвоить результат переменной, например: myInt = log(some_int_variable).

+1

'int main (void) {}' и 'int main() {}' - одно и то же. Это имеет значение только для прототипов функции *. – dreamlax

+2

@dreamlax это не то же самое, например, это 'int main() {main (1)};' является UB, а 'int main (void) {main (1)};' является нарушением ограничения. – ouah

+1

для получения дополнительной информации см. Мои пункты здесь: http://stackoverflow.com/a/9444492/1119701 – ouah

0

Похоже, что старый стиль объявления аргументов функции. Это эквивалентно int main(void). Некоторые компиляторы по-прежнему принимают его, а некоторые нет. Например, этот код компилируется в двух составителей я пробовал:

void main(i, j) { 
    int; 
    long; 

    i = 12; 
    j = 123456; 
    printf("%d %d\n", i, j); 
} 

Ответ на Untyped arguments in a C function declaration имеет более точное определение для этого случая.

В любом случае, это не рекомендуется, поэтому можем ли мы просто придерживаться «нормального» способа декларирования функций, пожалуйста? :)

+1

Что вы показываете, это не стиль K & R, как я его знаю. В стиле K & R типы объявляются перед открывающей скобкой вместе с их именами. Здесь они определены внутри функции без имен. Это еще один стиль определения? Или, может быть, 'i, j' являются' int' по умолчанию, а 'int; long;' игнорируются? – ugoren

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