Чому повертати NULL з main ()?


10

Іноді я бачу кодери, які використовують NULLяк повернене значення main()в програмах C і C ++, наприклад щось подібне:

#include <stdio.h>

int main()
{
    printf("HelloWorld!");

    return NULL;
} 

Коли я компілюю цей `код з gcc, я отримую попередження:

попередження: return робить ціле число від вказівника без виведення [-Wint-convert]

що розумно, оскільки макрос NULLповинен бути розширений до, (void*) 0а значення, що повертається основним, має тип int.

Коли я роблю коротку програму C ++:

#include <iostream>
using namespace std;

int main()
{
    cout << "HelloWorld!";

    return NULL;
}

І компілюючи його з g ++, я отримую еквівалентне попередження:

попередження: перехід до типу "int", що не вказує, з NULL [-Wconversion-null]

Але чому вони використовують NULLяк повернене значення, main()коли воно кидає попередження? Це просто поганий стиль кодування?


  • Яка причина використовувати NULLзамість 0зворотного значення, main()незважаючи на попередження?
  • Чи визначено це реалізацією, якщо це підходить чи ні, і якщо так, чому будь-яка реалізація хотіла б повернути значення вказівника?

4
Ви повинні запитати їх безпосередньо.
juanchopanza

5
"чому вони використовують NULL як повернене значення main ()" - ми не робимо. Автор цього коду робить. Мені було б цікаво почути їх спробу вияснити, чому.
WhozCraig

1
@Vlad з Москви, так, але мені довелося перевірити, чи дійсно це 0. ^^ - EXIT_FAILUREце 8, і, здається, використання 1 не дуже добре для провалу, оскільки це колись використовується як успіх у деяких програмах.
Ваельміо

2
@RobertSsupportsMonicaCellio, якщо це справді відповідь, яку ти отримав, це сумно. По-перше, це не має сенсу (було б більше сенсу, якби воно було скрізь, а не де-небудь ). По-друге, це розпродаж. Якщо ви пишете код, краще мати хороший компас про те, чи правильно він; не просто йти з цим, тому що це, здається, робиться ... кимось. Вам здається, що голка вказує правильний напрямок (таким чином, чому ви запитуєте); не стільки людина, яка написала цей код, а потім годувала вас цією відповіддю, як причиною.
WhozCraig

2
В c цілком справедливо визначити NULLпокажчик як 0(без відтворення на void *). У цьому випадку вада залишається непоміченою і не генерує попередження. Це все ще не те, для чого слід використовувати NULL.
Ctx

Відповіді:


14

що розумно

Так.

тому що макрос NULLслід розширити до(void*) 0

Ні. У C ++ макрос NULL не повинен розширюватися до (void*) 0[support.types.nullptr]. Це може зробити це лише в C.

У будь-якому випадку, написання такого коду вводить в оману, оскільки NULLпередбачається посилання на константу нульового покажчика , незалежно від того, як він реалізований. Використання його замість а intє логічною помилкою.

  • Яка причина використовувати NULLзамість 0 як зворотне значення, main()незважаючи на попередження?

Невігластво. Немає вагомих причин для цього.

  • Чи визначено це реалізацією, якщо це підходить чи ні, і якщо так, чому будь-яка реалізація хотіла б повернути значення вказівника?

Ні, це ніколи не доречно . Це залежить від того, чи дозволяє це компілятор . Відповідний компілятор C ++ цілком може це дозволити без попередження.


1
Мій звичайний удар: не визначено, чи компілятор дозволяє це; це специфічно для реалізації . У стандарті "визначено реалізацією" означає, що реалізація повинна документувати те, що вона робить.
Піт Бекер

@ PeteBecker Я робив паузу, коли писав це, але все одно продовжував роботу (тому що "специфічні для реалізації" та подібні фрази просто звучать неприродно). Але ти прав, я його зміню.
Конрад Рудольф

Мені здається, що єдиною причиною "визначеної" реалізації звучить природно є те, що люди звикли бачити це неправомірним. <g>
Піт Бекер

8

Коли я компілюю цей `код з gcc, я отримую попередження:

warning: return makes integer from pointer without a cast

Це відбувається тому, що ви компілюєте параметри компілятора lax. Використовуйте суворі стандартні настройки C, -std=c11 -pedantic-errorsі ви отримаєте очікувану помилку компілятора, в реалізаціях, де NULLрозширюється на константу нульового покажчика (void*)0. Див . Питання "Вказівник на ціле / ціле число від вказівника без виступу" .

У реалізаціях, де NULLрозширюється 0, код суворо відповідає стандарту, але дуже поганому стилю, непереносному і найгірше: повна нісенітниця.

І компілюючи його з g ++, я отримую еквівалентне попередження:

warning: converting to non-pointer type int from NULL [-Wconversion-null]

На C ++ 11 і вище NULLне слід використовувати, а використовувати nullptr. Повертати його з main () неправильно незалежно. NULLзавжди розширюється на 0C ++, тому строго кажучи, це спрацює, але це дуже поганий стиль і найгірше: повна дурниця.

Це просто поганий стиль кодування?

Не просто поганий, але і дурницький стиль кодування без будь-якого обґрунтування. Програміст, який це написав, був некомпетентним.


2

Це просто поганий стиль кодування?

Гірше. Правильний спосіб вказати, що програма закінчена

#include <stdlib.h>

int main (void)
{
    return EXIT_SUCCESS;
}

1
Це чиста педантичність. Відповідно до стандарту C, аргумент 0 до exit()(або 0 повернене значення від основного) означає те саме, що EXIT_SUCCESS.
москва

А оскільки c99 можна просто опустити returnз main. Отже, більш "правильною" версією вашої програми є int main(void){};-)
mosvy

1

В? Деякі / багато / всі? Реалізація C ++ NULL- це макрос, розширений до 0.

Це при розширенні по суті дає return 0. Що є дійсним значенням повернення.

Це просто поганий стиль кодування?

Так.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.