ข้อผิดพลาด: ไม่ได้ประกาศ 'NULL' ในขอบเขตนี้


120

ฉันได้รับข้อความนี้เมื่อรวบรวม C ++ บน gcc 4.3

error: NULL was not declared in this scope

มันปรากฏขึ้นและหายไปและฉันไม่รู้ว่าทำไม ทำไม?

ขอบคุณ


2
บางทีคุณอาจไม่ได้ประกาศ NULL ในขอบเขตที่ข้อความนั้นมาจาก?
Paul Tomblin

1
คุณควรโพสต์โค้ดที่สมบูรณ์ซึ่งทำให้เกิดข้อผิดพลาดอย่างน้อยที่สุด มิฉะนั้นจะเป็นการยากมากที่จะบอกว่าเกิดอะไรขึ้นโดยเพียงแค่ดูสตริงข้อผิดพลาด
Naveen

คำตอบ:


179

NULLไม่ใช่คำหลัก เป็นตัวระบุที่กำหนดไว้ในส่วนหัวมาตรฐานบางส่วน คุณสามารถรวม

#include <cstddef>

ที่จะมีมันอยู่ในขอบเขตรวมถึงพื้นฐานอื่น ๆ std::size_tบางอย่างเช่น


พระเจ้าฉันเอาแต่ใจกับ Java (null เป็นคีย์เวิร์ด) จนฉันไม่เคยคิดว่า NULL จะไม่ใช่คีย์เวิร์ดใน c ++ ขอบคุณ :)
Stefan Hendriks

14
อันที่จริงมันไม่ใช่คีย์เวิร์ดใน Java เช่นกัน
Man of One Way

4
@ManofOneWay No มีอยู่ใน Java เพียงแค่สะกดด้วยตัวพิมพ์เล็กทั้งหมดแทนที่จะเป็นตัวพิมพ์ใหญ่
Ataraxia

8
@ZettaSuro ไม่ได้บอกว่าไม่มีอยู่จริง ฉันแค่บอกว่ามันไม่ใช่คีย์เวิร์ด
Man of One Way

8
ตอนนี้ C ++ 11 ได้รับการสนับสนุนโดยคอมไพเลอร์โดยทั่วไปแล้วมันอาจคุ้มค่าที่จะกล่าวถึงnullptrคำหลักซึ่งเป็นคำหลักจริงและไม่จำเป็นต้องใช้#includes ใด ๆ มัน typesafe NULLยังมีมากกว่า
templatetypedef

38

GCC กำลังดำเนินการไปสู่ ​​C ++ 11 ซึ่งอาจเป็นเหตุผลว่าทำไมคุณต้องรวมcstddefเพื่อใช้ค่าคงที่NULL วิธีที่แนะนำใน C ++ 11 คือการใช้คีย์เวิร์ด nullptrใหม่ซึ่งใช้งานใน GCC ตั้งแต่เวอร์ชัน 4.6 nullptrไม่สามารถแปลงเป็นชนิดอินทิกรัลได้โดยปริยายดังนั้นจึงสามารถใช้เพื่อแยกแยะการเรียกไปยังฟังก์ชันที่โอเวอร์โหลดสำหรับทั้งตัวชี้และชนิดอินทิกรัล:

void f(int x);
void f(void * ptr);

f(0);  // Passes int 0.
f(nullptr);  // Passes void * 0.

1
แต่ยังคงเป็นพฤติกรรมแปลก ๆ ! แม้แต่การคอมไพล์โค้ดของฉันด้วย -std = c ++ 98 GCC ก็ยังไม่รู้จักมาโคร NULL และมันรับรู้เฉพาะ nullptr ที่มี c ++ 11 หรือ gnu ++ 11 เป็นอาร์กิวเมนต์สำหรับ -std
ฟาโรห์

2
มาตรฐาน C ++ ได้ระบุไว้แล้วในปี 1998 ว่า NULL ถูกกำหนดไว้ใน cstddef - เวอร์ชันคอมไพเลอร์ใหม่จะปฏิบัติตามมาตรฐานอย่างเคร่งครัดมากขึ้นเนื่องจากต้องใช้ nullptr รหัส (ผิดพลาด) ของคุณได้รวบรวมด้วย GCC เวอร์ชันก่อนหน้า แต่คงเป็นเรื่องยากที่จะใช้งานร่วมกับ GCC เวอร์ชันก่อนหน้าได้นอกเหนือจากเวอร์ชันมาตรฐาน C ++ ก่อนหน้านี้
Seppo Enarvi

NULLไม่เคยมีคำหลักในตัว เป็นมาโครที่กำหนดไว้ในส่วนหัว C มาตรฐานหลายตัวรวมถึง<stddef.h>(หรือ<cstddef>) gcc "ก้าวสู่ C ++ 11" ส่งผลอย่างไร ฉันไม่เห็นอะไรเลยในคำถามที่บอกเป็นนัยว่าโค้ด (ที่มองไม่เห็น) คอมไพล์ด้วย gcc / g ++ เวอร์ชันก่อนหน้าหรือมาตรฐานภาษาเวอร์ชันก่อนหน้า
Keith Thompson

1
นั่นเป็นเพียงสิ่งที่ฉันกล่าวไว้ข้างต้น: ใน C ++ 98 ถูกกำหนดไว้ใน cstddef แล้ว ยังคง gcc (และคอมไพเลอร์อื่น ๆ ด้วย) ยอมรับรหัสที่ใช้ NULL โดยไม่รวม cstddef ก่อน ฉันค่อนข้างแน่ใจว่าโค้ด (ที่มองไม่เห็น) ที่เป็นปัญหาที่รวบรวมด้วยเวอร์ชันก่อนหน้านี้แม้ว่าจะไม่เป็นไปตามมาตรฐานอย่างเคร่งครัดก็ตาม ตอนนี้ฉันคาดเดาได้ว่าพฤติกรรมที่เข้มงวดขึ้นของเวอร์ชันสมัยใหม่นี้เกิดจากการพัฒนาคอมไพเลอร์เพื่อรองรับไวยากรณ์ C ++ 11
Seppo Enarvi

10

NULLไม่ใช่คำหลัก มันเป็นการแทนที่มาโครสำหรับ 0 และเข้ามาstddef.hหรือcstddefฉันเชื่อ คุณไม่มี#includedไฟล์ส่วนหัวที่เหมาะสมดังนั้น g ++ จึงมองNULLว่าเป็นชื่อตัวแปรทั่วไปและคุณยังไม่ได้ประกาศ


5

เพื่อตอบคำตอบอื่น ๆ : หากคุณใช้ C ++ 11 ให้ใช้nullptrซึ่งเป็นคีย์เวิร์ดที่หมายถึงตัวชี้โมฆะที่ชี้ไปที่โมฆะ (แทนNULLซึ่งไม่ใช่ประเภทตัวชี้)



0

คุณสามารถประกาศแมโคร NULL เพิ่มหลังจาก # ของคุณรวมถึง:

#define NULL 0

หรือ

#ifndef NULL
#define NULL 0
#endif

ไม่ ";" ท้ายคำแนะนำ ...

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