Ще работи ли автоматичното приспадане на тип връщане за основния?

Ще мога ли да направя следното за основната функция в C++1y (C++14):

auto main()
{
    // ...
}

Така че върнатият тип автоматично ще бъде int, въпреки че не е необходимо да използваме изрично return 0;?


person template boy    schedule 16.06.2013    source източник
comment
Това не е практически проблем, с който всъщност се сблъсквате, или не е?   -  person Daniel Fischer    schedule 16.06.2013
comment
@DanielFischer На кого му пука? Това е интересен (безполезен) краен случай.   -  person David    schedule 16.06.2013
comment
Не знам дали това е специално въведено в правилата, но ако не е, очаквайте void.   -  person Puppy    schedule 16.06.2013
comment
Защо? auto е с една буква по-дълго от int.   -  person milleniumbug    schedule 16.06.2013
comment
@Dave, аз не. Просто ми е интересно защо възникна въпросът.   -  person Daniel Fischer    schedule 16.06.2013
comment
Писателят на компилатора ще трябва да напише специално правило за това. Защо биха го направили?   -  person David Heffernan    schedule 16.06.2013
comment
@DavidHeffernan така или иначе трябваше да напишат специално правило за имплицитно return 0;.   -  person Bartek Banachewicz    schedule 16.06.2013
comment
@BartekBanachewicz Обзалагам се, че създателите на стандарти нямаше да пишат това сега, ако можеха да започнат отначало   -  person David Heffernan    schedule 16.06.2013
comment
@DavidHeffernan: Обзалагам се, че биха го направили, тъй като това е сравнително скорошно допълнение (вярвам). Но се обзалагам, че ако обмислят тази точка, те просто ще забранят използването на auto като тип връщане на main().   -  person Ben Voigt    schedule 16.06.2013
comment
Премахнах вашия таг C++14. Този мета въпрос стигна до консенсус да се изчака окончателната чернова на стандарта, преди да се използва вместо него на C++1y.   -  person chris    schedule 25.06.2013
comment
Какво ще кажете само за auto { ... }. Очевидно искам функция за стартиране тук; автоматично извеждане на декларацията! :)   -  person Kaz    schedule 10.06.2014


Отговори (1)


Не, няма да бъде позволено. Параграф 7.1.6.4/10 от C++14 Standard Draft N3690 уточнява:

Ако функция с деклариран тип на връщане, която използва тип заместител, няма изрази return, типът на връщане се извежда сякаш от оператор return без операнд в затварящата скоба на тялото на функцията. [...]

Това означава, че пропускането на израз return в main() ще направи неговия тип void.

Специалното правило, въведено от параграф 3.6.1/5 относно изтичането на края на main(), уточнява:

[...] Ако контролът достигне края на main, без да се натъкне на оператор return, ефектът е изпълнението

return 0;

Формулировката гласи, че „ефектът“ по време на изпълнението на програмата е същият, както ако е налице return 0, а не че оператор return ще бъде добавен към програмата (което би повлияло на дедукцията на типа според цитирания параграф).

РЕДАКТИРАНЕ:

Има Доклад за дефект за това ( с любезното съдействие на Йоханес Шауб ):

Предложена резолюция (ноември 2013 г.):

Променете 3.6.1 [basic.start.main] параграф 2, както следва:

Реализацията не трябва да предефинира основната функция. Тази функция не трябва да се претоварва. Той трябва да има деклариран тип връщане от тип int, но в противен случай неговият тип е дефиниран от изпълнението. Всички реализации Внедряване позволява и двете

  • функция на () връщаща int и
  • функция на (int, указател към указател към char), връщаща int

като тип...

person Andy Prowl    schedule 16.06.2013
comment
Но извеждането на връщания тип като int ефект от изпълнението на return 0; ли е? - person Ben Voigt; 16.06.2013
comment
@BenVoigt: Е, ефектът не е този от добавянето на return 0, а 7.1.6.4/10 указва Ако функция с деклариран тип връщане, която използва тип заместител, няма изрази за връщане [...]. Изтичането от края на main не добавя израз return, така че останалата част от изречението трябва да се приложи и типът на връщането трябва да се изведе като void - person Andy Prowl; 16.06.2013
comment
Искате да кажете, че ефектът от изпълнението означава, че не се случват ефекти по време на компилиране? Съществува ли такова концептуално разграничение? Трудно ми е да повярвам в това. - person Johannes Schaub - litb; 16.06.2013
comment
@JohannesSchaub-litb: Казвам, че компилаторът ще подреди нещата зад капака, така че изпълнението да бъде идентично с това, което би се получило, ако оператор return 0; присъства изрично в програмата. - person Andy Prowl; 16.06.2013
comment
ААА разбирам. Предполагам, че може и така да се чете. Но въпреки това беше публикуван доклад за проблем за това от някакъв разработчик на clang, за да изясни спецификацията тук. - person Johannes Schaub - litb; 16.06.2013
comment
@Andy: Значи казваш, че съответстващият компилатор може да отхвърли кода като неправилно оформен, но ако продължи с компилация, поведението по време на изпълнение трябва да е същото, както ако изразът return 0; присъства изрично, поне до присъствието или липса на недефинирано поведение? - person Ben Voigt; 16.06.2013
comment
@Ben: Не съм сигурен, че разбирам. Казвам, че компилаторът трябва да отхвърли кода като неправилно оформен, защото липсата на изричен израз return би накарала дедукцията на типа да заключи, че main има върнат тип void, което е незаконно - person Andy Prowl; 16.06.2013
comment
@Andy: Но необходима ли е диагностика за void main() или това е просто недефинирано поведение? - person Ben Voigt; 16.06.2013
comment
@Ben: 3.6.1/2 не уточнява, че не се изисква диагностика, така че компилаторът трябва да издаде диагностика - person Andy Prowl; 16.06.2013
comment
Съгласно дискусията на основния рефлектор, това няма да бъде разрешено дори ако main съдържа изявление за връщане, връщащо int. main всъщност е повторно деклариране на обект във времето за изпълнение и неговият деклариран тип на връщане трябва да съответства на този обект. - person Richard Smith; 01.08.2013
comment
И така, какъв е ефектът от return 0; във функция, която връща void? - person user253751; 09.10.2014
comment
@immibis: Не съм сигурен, че разбирам смисъла на въпроса ви, така или иначе връщането на всичко от функция, чийто тип на връщане е void, е неправилно и ще причини грешка на компилатора. - person Andy Prowl; 10.10.2014