lỗi: 'NULL' không được khai báo trong phạm vi này


119

Tôi nhận được thông báo này khi biên dịch C ++ trên gcc 4.3

error: NULL was not declared in this scope

Nó xuất hiện và biến mất mà tôi không biết tại sao. Tại sao?

Cảm ơn.


2
Có lẽ bạn chưa khai báo NULL trong phạm vi nơi thông báo đến từ?
Paul Tomblin

1
Ít nhất bạn nên đăng đoạn mã hoàn chỉnh gây ra lỗi. Nếu không, sẽ rất khó để biết điều gì đang xảy ra nếu chỉ nhìn vào chuỗi lỗi.
Naveen

Câu trả lời:


178

NULLkhông phải là một từ khóa. Đó là một số nhận dạng được xác định trong một số tiêu đề chuẩn. Bạn có thể bao gồm

#include <cstddef>

Để có nó trong phạm vi, bao gồm một số điều cơ bản khác, như std::size_t.


Chúa ơi, tôi làm hỏng Java (null là một từ khóa) đến nỗi tôi chưa bao giờ nghĩ rằng NULL sẽ không phải là một từ khóa trong c ++. Cảm ơn :)
Stefan Hendriks 4/10/11

14
Thực ra nó cũng không phải là một từ khóa trong Java.
Man of One Way

4
@ManofOneWay Không, nó tồn tại trong Java, nó chỉ được đánh vần bằng tất cả chữ thường thay vì viết hoa.
Ataraxia

8
@ZettaSuro Tôi không nói nó không tồn tại. Tôi chỉ nói rằng nó không phải là một từ khóa.
Man of One Way

8
Bây giờ C ++ 11 được hỗ trợ chung hơn bởi các trình biên dịch, nên có thể cần nhắc đến nullptrtừ khóa, đây là một từ khóa thực tế và không yêu cầu bất kỳ #includes. Nó cũng an toàn hơn NULL.
templatetypedef.

38

GCC đang thực hiện các bước hướng tới C ++ 11, đó có thể là lý do tại sao bây giờ bạn cần bao gồm cstddef để sử dụng hằng số NULL . Cách ưa thích trong C ++ 11 là sử dụng từ khóa nullptr mới , được triển khai trong GCC kể từ phiên bản 4.6. nullptr không hoàn toàn có thể chuyển đổi thành kiểu tích phân, vì vậy nó có thể được sử dụng để phân biệt lời gọi đến một hàm đã được nạp chồng cho cả kiểu con trỏ và tích phân:

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

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

1
Nhưng nó vẫn là một hành vi kỳ lạ! Ngay cả khi biên dịch mã của tôi với -std = c ++ 98 GCC vẫn không nhận ra macro NULL và Nó chỉ nhận dạng nullptr với c ++ 11 hoặc gnu ++ 11 làm đối số cho -std.
pharaoh

2
Tiêu chuẩn C ++ đã tuyên bố vào năm 1998 rằng NULL được định nghĩa trong cstddef - các phiên bản trình biên dịch mới chỉ tuân theo tiêu chuẩn nghiêm ngặt hơn vì chúng cần triển khai nullptr. Mã (bị lỗi) của bạn đã được biên dịch với các phiên bản GCC trước đó, nhưng sẽ khó tương thích ngược với các phiên bản GCC trước đó, ngoài các phiên bản chuẩn C ++ trước đó.
Seppo Enarvi

NULLchưa bao giờ là một từ khóa được tích hợp sẵn; nó là một macro được xác định trong một số tiêu đề C tiêu chuẩn, bao gồm <stddef.h>(hoặc <cstddef>). Gcc "thực hiện các bước hướng tới C ++ 11" ảnh hưởng như thế nào đến điều này? Tôi không thấy gì trong câu hỏi ngụ ý rằng mã (không nhìn thấy) được biên dịch với các phiên bản trước đó của gcc / g ++ hoặc với các phiên bản trước đó của tiêu chuẩn ngôn ngữ.
Keith Thompson

1
Đó chỉ là những gì tôi đã nói ở trên: Đã có trong C ++ 98, nó đã được định nghĩa trong cstddef. Vẫn chấp nhận mã gcc (và các trình biên dịch khác) sử dụng NULL mà không bao gồm cstddef trước. Tôi khá chắc chắn cũng là mã (không nhìn thấy) được đề cập được biên dịch với các phiên bản trước đó, mặc dù nó không tuân thủ tiêu chuẩn nghiêm ngặt. Bây giờ tôi chỉ đoán rằng hành vi chặt chẽ hơn này của các phiên bản hiện đại là do sự phát triển của trình biên dịch để hỗ trợ cú pháp C ++ 11.
Seppo Enarvi, 24/09/13

10

NULLkhông phải là một từ khóa; nó là một thay thế macro cho 0 và có stddef.hhoặc cstddef, tôi tin. Bạn không #includedcó tệp tiêu đề thích hợp, vì vậy g ++ xem NULLnhư một tên biến thông thường và bạn chưa khai báo nó.


5

Để hoàn thành các câu trả lời khác: Nếu bạn đang sử dụng C ++ 11, hãy sử dụng nullptr, đây là một từ khóa có nghĩa là con trỏ void trỏ đến null. (thay vì NULL, không phải là loại con trỏ)


0

NULL cũng có thể được tìm thấy trong:

#include <string.h>

String.h sẽ kéo NULL từ một nơi khác.


0

Bạn có thể khai báo macro NULL. Thêm điều đó sau #includes của bạn:

#define NULL 0

hoặc là

#ifndef NULL
#define NULL 0
#endif

Không ";" ở cuối hướng dẫn ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.