До сих пор думал, что указывать возвращаемое значение для любой функции в C++ совершенно обязательно даже в том случае, если данная функция возвращает int, в отличие от языка C. Недавно, просматривая какой-то видеоурок, наткнулся на то, что автор не указывает тип возвращаемого значения у main в C++, при этом компиляция программы происходит без каких-либо ошибок. Почему? К сожалению, обратить внимание на среду разработки я тогда не догадался.
В том же видеоуроке увидел использование конструкции вида
#include "stdio.h";
В данном случае компиляция не была выполнена вообще, выдав сообщение об ошибке.
Попробовал выполнить такой же код в Visual Studio — код скомпилировался. Почему? Может, дело в том, что автор писал на C, а не на C++ или как?
Здравствуйте, YourLastSong, Вы писали:
YLS>Здравствуйте, уважаемые господа.
YLS>До сих пор думал, что указывать возвращаемое значение для любой функции в C++ совершенно обязательно даже в том случае, если данная функция возвращает int, в отличие от языка C. Недавно, просматривая какой-то видеоурок, наткнулся на то, что автор не указывает тип возвращаемого значения у main в C++, при этом компиляция программы происходит без каких-либо ошибок. Почему? К сожалению, обратить внимание на среду разработки я тогда не догадался.
По стандарту С++ у main можно не писать return, если предполагается возвращать ноль. Больше нигде так делать нельзя.
Здравствуйте, YourLastSong, Вы писали:
YLS>Про return я итак знаю, интересует именно тип возвращаемого значения, например int main.
И в языке C, и в языке C++ для функции main должны поддерживаться две сигнатуры:
int main(void);
и
int main(int argc, char* argv[]);
Поддержка другие вариантов, с другим набором аргументов или с другим типом возвращаемого значения, — implementation-defined. То есть делается по желанию разработчиков компилятора.
Здравствуйте, YourLastSong, Вы писали:
W>>По стандарту С++ у main можно не писать return, если предполагается возвращать ноль. Больше нигде так делать нельзя.
YLS>Про return я итак знаю, интересует именно тип возвращаемого значения, например int main.
так же говорится, что main() не может возвращать void.
но микрософтстудийный компилер не славится соответствием стандарту(в прочем как и борланд). так что ничего удивительного.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, YourLastSong, Вы писали:
W>>>По стандарту С++ у main можно не писать return, если предполагается возвращать ноль. Больше нигде так делать нельзя.
YLS>>Про return я итак знаю, интересует именно тип возвращаемого значения, например int main. X>так же говорится, что main() не может возвращать void.
Где, простите, такое говориться?
В С++ пункт 3.6.2 Main function (2): > It shall have a return type of type int, but otherwise its type is implementation-defined.
Аналогичный пункт есть и в C99 — 5.1.2.2.1 Program startup — делайте что хотите, хоть int, хоть void, если это поддерживается компилятором.
WM>Поддержка другие вариантов, с другим набором аргументов или с другим типом возвращаемого значения, — implementation-defined. То есть делается по желанию разработчиков компилятора.
Я имею ввиду то, что в C вполне возможна конструкция вида
main ()
{
return 0;
}
В таком случае компилятор будет, разумеется, считать, что тип возвращаемого значения именно int.
В C++ такого вроде нет, поэтому такая конструкция будет возможна только в C, разве нет?
Здравствуйте, watch-maker, Вы писали:
WM>Здравствуйте, niXman, Вы писали:
X>>Здравствуйте, YourLastSong, Вы писали:
W>>>>По стандарту С++ у main можно не писать return, если предполагается возвращать ноль. Больше нигде так делать нельзя.
YLS>>>Про return я итак знаю, интересует именно тип возвращаемого значения, например int main. X>>так же говорится, что main() не может возвращать void. WM>Где, простите, такое говориться? WM>В С++ пункт 3.6.2 Main function (2): >> It shall have a return type of type int, but otherwise its type is implementation-defined. WM>Аналогичный пункт есть и в C99 — 5.1.2.2.1 Program startup — делайте что хотите, хоть int, хоть void, если это поддерживается компилятором.
да, простите, ошибся.
3.6.1-2:
An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, YourLastSong, Вы писали:
YLS>Я имею ввиду то, что в C вполне возможна конструкция вида
YLS>main () YLS>{ YLS>return 0; YLS>}
YLS>В таком случае компилятор будет, разумеется, считать, что тип возвращаемого значения именно int.
YLS>В C++ такого вроде нет, поэтому такая конструкция будет возможна только в C, разве нет?
Правило, что функиция возвращает int, если явно не указано другое, действительно было в языке C когда-то очень давно. Сейчас такого в языке нет. Это ошибка и в C++ и в C.
WM>Правило, что функиция возвращает int, если явно не указано другое, действительно было в языке C когда-то очень давно. Сейчас такого в языке нет. Это ошибка и в C++ и в C.
Здравствуйте, watch-maker, Вы писали:
WM>Здравствуйте, YourLastSong, Вы писали:
YLS>>Я имею ввиду то, что в C вполне возможна конструкция вида
YLS>>main () YLS>>{ YLS>>return 0; YLS>>}
YLS>>В таком случае компилятор будет, разумеется, считать, что тип возвращаемого значения именно int.
YLS>>В C++ такого вроде нет, поэтому такая конструкция будет возможна только в C, разве нет?
WM>Правило, что функиция возвращает int, если явно не указано другое, действительно было в языке C когда-то очень давно. Сейчас такого в языке нет. Это ошибка и в C++ и в C.
хотелось бы увидеть пруф, пожалуйста.
ибо цитаты из стандарта никак об этом не говорят.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, YourLastSong, Вы писали:
WM>>Правило, что функиция возвращает int, если явно не указано другое, действительно было в языке C когда-то очень давно. Сейчас такого в языке нет. Это ошибка и в C++ и в C.
YLS>Точно? Когда это появилось в C вообще?
Появилось очень давно. Окончательно исчезло тоже давно — в C99.
Сейчас в языке C эта ситуация называется термином "constraint violation", и компилятор обязан в этом случае сгенерировать соответствующее диагностическое сообщение, что компиляторы успешно и делают.
Разумеется, специально никто эту конструкцию не закрывал, так как диагностическоого сообщения достаточно, и можно продолжать компиляцию. Да и в целях совместимости, тоже, увы, иногда это нужно, — поддержку старого кода никто не отменял.
Здравствуйте, niXman, Вы писали:
WM>>Правило, что функиция возвращает int, если явно не указано другое, действительно было в языке C когда-то очень давно. Сейчас такого в языке нет. Это ошибка и в C++ и в C.
X>хотелось бы увидеть пруф, пожалуйста. X>ибо цитаты из стандарта никак об этом не говорят.
Пруф чего?
Что это правило появилось очень давно? — читайте K&R.
Что в C была практика implicit-int (и не только) для функций — читайте Ansi-C: >If the expression that precedes the parenthesized argument list in >a function call consists solely of an identifier, and if no >declaration is visible for this identifier, the identifier is >implicitly declared exactly as if, in the innermost block containing >the function call, the declaration > > extern int identifier(); > >appeared.
Что в С можно было объявлять функции без указания типов? — читайте примеры в Ansi-C:
>Then the definition of g might read
>
> g(int (*funcp)(void))
> {
> /*...*/ (*funcp)() /* or funcp() ... */
> }
Что сейчас такого правила нет? — читайте C99.
Там даже эти примеры переписали:
>Then the definition of g might read
>void g(int (*funcp)(void))
> {
> /* ... */
> (*funcp)() /* or funcp() ... */
> }
Здравствуйте, watch-maker, Вы писали:
WM>В С++ пункт 3.6.2 Main function (2): >> It shall have a return type of type int, but otherwise its type is implementation-defined.
Эта фраза переводится так: "[Функция main] обязана возвращать значение типа int; в остальном её тип определяется реализацией".
Иными словами, сигнатура функции main определяется реализацией, за исключением возвращаемого типа, который обязан быть int.
watch-maker:
X>>так же говорится, что main() не может возвращать void. WM>Где, простите, такое говориться? WM>В С++ пункт 3.6.2 Main function (2): >> It shall have a return type of type int, but otherwise its type is implementation-defined.
Там имелось в виду, что количество параметров и их типы — implementation-defined. Тип возврата должен быть int. Если он не int, то требуется выдача диагностического сообщения (при этом код может успешно компилиться на основаниях п. 1.4/8).
On 15.09.2011 21:23, YourLastSong wrote:
> отличие от языка C. Недавно, просматривая какой-то видеоурок, наткнулся на то, > что автор не указывает тип возвращаемого значения у main в C++, при этом > компиляция программы происходит без каких-либо ошибок. Почему?
main -- особый случай, его компилятор по-особому обрабатывает, часто прощая
нестандартность. Это традиция такая. Нестандартная.
niXman:
X>все таки, тип возвращаемого значения обязан быть int?
Если у функции main он не int, то программа является ill-formed. В таком случае компилятор должен уметь выдавать диагностическое сообщение, но при этом имеет право успешно скомпилить программу. Например, Intel C++ 12.0 успешно компилирует следующую программу
void main() {}
но при этом выдаёт
warning #1079: return type of function "main" must be "int"
X>возвращаемый тип действительно не является частью сигнатуры?
В случае обычной функции (не являющейся специализацией шаблона) — не является. Определение понятия "сигнатура функции" дано в C++11 — 1.3.17:
signature
<function> name, parameter type list (8.3.5), and enclosing namespace (if any)
Сигнатура функции и тип функции — не одно и то же (эти два понятия часто путают).
YourLastSong:
M>>Тип возврата не является частью сигнатуры функции.
YLS>Я думал, что в него входит тип возвращаемого функцией значения и аргументы функции, разве нет?
YourLastSong:
C>>В этом коде лишняя точка с запятой.
YLS>Я понял, но почему данный код в одних компиляторах выдаёт ошибку, а в других прекрасно компилируется?
YLS>Неужели об этом ничего не сказано в стандарте?
YLS>Вообще хоть что-то об этом в стандарте есть или нет всё же?
Сказано, что поведение не определено (см. 16.2/4). Как компилятор захочет, так и поступит.