ทำไมส่งคืน NULL จาก main ()


10

บางครั้งฉันเห็นโคเดอร์ที่ใช้NULLเป็นค่าส่งคืนของmain()ในโปรแกรม C และ C ++ ตัวอย่างเช่น:

#include <stdio.h>

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

    return NULL;
} 

เมื่อฉันรวบรวมรหัส `นี้กับ gcc ฉันได้รับคำเตือน:

คำเตือน: return ทำให้จำนวนเต็มจากตัวชี้โดยไม่ต้องส่ง [-Wint-conversion]

ซึ่งมีความสมเหตุสมผลเนื่องจากแมโครNULLจะถูกขยายไปและค่าตอบแทนของหลักจะเป็นประเภท(void*) 0int

เมื่อฉันสร้างโปรแกรม 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
@ วลาจากมอสโกใช่ แต่ฉันต้องตรวจสอบว่ามันเป็นจริงหรือเปล่า ^^ - EXIT_FAILUREคือ 8 และดูเหมือนว่าการใช้ 1 นั้นไม่ดีสำหรับความล้มเหลวเพราะบางครั้งก็ใช้เป็นความสำเร็จในบางโปรแกรม
Waelmio

2
@RobertSsupportsMonicaCellio ถ้านั่นเป็นคำตอบที่คุณได้รับจริงๆมันช่างน่าเศร้า ครั้งแรกมันไม่สมเหตุสมผล (จะสมเหตุสมผลกว่าถ้ามันมีอยู่ทุกที่มากกว่าทุกที่ ) ประการที่สองเป็นการขายออก หากคุณกำลังเขียนโค้ดคุณควรมีเข็มทิศที่ดีว่ามันถูกต้องหรือไม่ ไม่ใช่แค่ไปกับมันเพราะนั่นเป็นวิธีที่ ... ใครบางคนทำ ดูเหมือนว่าคุณจะมีเข็มชี้ไปในทิศทางที่ถูกต้อง ไม่มากนักที่เขียนรหัสนั้นแล้วป้อนคำตอบให้คุณด้วยเหตุผลว่าทำไม
WhozCraig

2
ใน c มันถูกต้องสมบูรณ์เพื่อกำหนดNULLตัวชี้เป็น0(โดยไม่ต้องร่ายไปvoid *) ในกรณีนี้ข้อบกพร่องจะไม่ถูกสังเกตและไม่สร้างคำเตือน มันยังไม่ใช่สิ่งที่ควรใช้เป็นค่าว่าง
Ctx

คำตอบ:


14

ซึ่งสมเหตุสมผล

ใช่.

เนื่องจากแมโครNULLจะถูกขยายเป็น(void*) 0

ไม่ใน C ++ แมโครNULL ต้องไม่ขยายเป็น(void*) 0[support.types.nullptr] มันสามารถทำได้ในซีเท่านั้น

ไม่ว่าจะด้วยวิธีใดการเขียนโค้ดในลักษณะนี้ทำให้เข้าใจผิดเนื่องจากNULLควรอ้างถึงค่าคงที่ตัวชี้โมฆะไม่ว่าจะใช้งานอย่างไร การใช้แทนintข้อผิดพลาดแบบลอจิคัล

  • เหตุผลที่จะใช้NULLแทน 0 เป็นค่าตอบแทนของmain()แม้คำเตือนคืออะไร?

ความไม่รู้ ไม่มีเหตุผลที่ดีที่จะทำเช่นนี้

  • มันเป็นตัวกำหนดการใช้งานหรือไม่ถ้าสิ่งนี้มีความเหมาะสมหรือไม่และหากเป็นเช่นนั้นเหตุใดการดำเนินการใด ๆ จึงต้องการรับค่าตัวชี้กลับมา

ไม่มีก็จะไม่เหมาะสม มันขึ้นอยู่กับการนำไปใช้ว่าคอมไพเลอร์อนุญาตหรือไม่ คอมไพเลอร์ที่สอดคล้องกับ C ++ อาจอนุญาตได้โดยไม่มีการเตือนล่วงหน้า


1
กระหน่ำปกติของฉัน: มันไม่ได้ใช้งานที่กำหนดไว้ว่าคอมไพเลอร์อนุญาตหรือไม่; มันเป็นimplemenation เฉพาะ ในมาตรฐาน "การดำเนินการที่กำหนดไว้" หมายความว่าการนำไปปฏิบัตินั้นต้องบันทึกว่ามันทำอะไร
Pete Becker

@PeteBecker ฉันได้หยุดชั่วคราวเมื่อเขียนมัน แต่ไปข้างหน้าต่อไป (เพราะ "การใช้งานเฉพาะ" และวลีที่คล้ายกันเพียงเสียงที่ผิดธรรมชาติ) แต่คุณถูกต้องฉันจะเปลี่ยน
Konrad Rudolph

ดูเหมือนว่าเหตุผลเดียวที่ "กำหนดการใช้งาน" ฟังดูเป็นธรรมชาติก็คือผู้คนมักจะเคยเห็นว่ามันถูกนำไปใช้ในทางที่ผิด <g>
Pete Becker

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]

เมื่อวันที่ 11 C ++ และอื่น ๆNULLไม่ควรใช้ - nullptrแทนการใช้งาน หากต้องการส่งคืนจาก main () จะไม่ถูกต้อง NULLขยาย0ใน C ++ เสมอดังนั้นการพูดอย่างเคร่งครัดจะใช้งานได้ แต่มันเป็นสไตล์ที่แย่มากและแย่ที่สุดของทั้งหมด: เรื่องไร้สาระสมบูรณ์

มันเป็นแค่รูปแบบการเข้ารหัสที่ไม่ดีเหรอ?

ไม่เพียง แต่ไม่ดีเท่านั้น แต่ยังมีรูปแบบการเข้ารหัสที่ไร้เหตุผล โปรแกรมเมอร์ที่เขียนมันไร้ความสามารถ


2

มันเป็นแค่รูปแบบการเข้ารหัสที่ไม่ดีเหรอ?

แย่ลง วิธีที่ถูกต้องในการระบุว่าโปรแกรมเสร็จสิ้นดี

#include <stdlib.h>

int main (void)
{
    return EXIT_SUCCESS;
}

1
นั่นคืออวดรู้อย่างแท้จริง ตามมาตรฐานซี 0 อาร์กิวเมนต์exit()(หรือค่า 0 กลับมาจากหลัก) EXIT_SUCCESSหมายความว่าเช่นเดียวกับ
mosvy

และตั้งแต่ c99 คุณก็สามารถละเว้นจากreturn mainดังนั้นโปรแกรมของคุณที่ "ถูกต้อง" มากกว่านี้ก็คือint main(void){};-)
mosvy

1

ในบาง / มาก / ทั้งหมด? C ++ การใช้งานเป็นแมโครขยายไปNULL0

return 0นี้เมื่อขยายผลในการช่วยให้ ซึ่งเป็นค่าส่งคืนที่ถูกต้อง

มันเป็นแค่รูปแบบการเข้ารหัสที่ไม่ดีเหรอ?

ใช่.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.