2012-05-04 33 views
7

Hãy xem chương trình nhỏ bé này.C++ 11 bao gồm <cstdlib> đôi khi C++ 03 sẽ không?

#include <iostream> 

int main(){ 

    int var = atoi("-99");  //convert string to int 
    var = abs(var);    //takes absolute value 
    std::cout << var+1 <<'\n'; //outputs 100 

    return EXIT_SUCCESS; 
} 

Biên dịch tạo ra các thông điệp lỗi sau đây:

$ g++ -o main main.cpp 
main.cpp: In function ‘int main()’: 
main.cpp:5:13: error: ‘atoi’ was not declared in this scope 
main.cpp:6:16: error: ‘abs’ was not declared in this scope 
main.cpp:9:10: error: ‘EXIT_SUCCESS’ was not declared in this scope 

thể hiểu được. Tất cả những điều này tồn tại trong tiêu đề "cstdlib" mà tôi đã bỏ qua.
Tuy nhiên, biên soạn với:

$ g++ -std=c++0x -o main main.cpp 

không tạo ra sự cố nào.


nhìn vào nguồn gốc của "cstdlib" tiêu đề, tôi thấy đoạn mã sau ở dưới cùng:

#ifdef __GXX_EXPERIMENTAL_CXX0X__ 
# if defined(_GLIBCXX_INCLUDE_AS_TR1) 
# error C++0x header cannot be included from TR1 header 
# endif 
# if defined(_GLIBCXX_INCLUDE_AS_CXX0X) 
# include <tr1_impl/cstdlib> 
# else 
# define _GLIBCXX_INCLUDE_AS_CXX0X 
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 
# define _GLIBCXX_END_NAMESPACE_TR1 
# define _GLIBCXX_TR1 
# include <tr1_impl/cstdlib> 
# undef _GLIBCXX_TR1 
# undef _GLIBCXX_END_NAMESPACE_TR1 
# undef _GLIBCXX_BEGIN_NAMESPACE_TR1 
# undef _GLIBCXX_INCLUDE_AS_CXX0X 
# endif 
#endif 

Tôi không chắc chắn nếu đó là có liên quan hay không .. tập tin tiêu đề đầy đủ Mã số here

câu hỏi cuối cùng của tôi là, tiêu chuẩn mới có đảm bảo rằng tất cả cstdlib sẽ được đưa vào không gian tên chung khi bạn đưa iostream vào không?

Tôi không thể tìm thấy bất kỳ tài liệu nào về vấn đề này. Xuất hiện theo cách đó với tôi, nó có xuất hiện theo cách đó với bạn không?

gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 
+3

Btw, danh hiệu này là hoàn toàn sai lệch. C++ 11 ** là ** C++. Nó không phải là một ngôn ngữ riêng biệt mới. –

Trả lời

15

câu hỏi cuối cùng của tôi là, không đảm bảo tiêu chuẩn mới mà tất cả các cstdlib sẽ được đưa vào tại một namespace toàn cục khi bạn bao gồm iostream?

Không. Bạn nên tự mình #include nếu cần chức năng của nó. Nếu bạn nhận được nó "miễn phí" với <iostream>, đó là dấu hiệu cho thấy tiêu đề <iostream> của bạn yêu cầu nó, nhưng sau đó bạn đang dựa vào một chi tiết triển khai của thư viện C++ của bạn.

Btw., #include <cstdlib> không đảm bảo mang các hàm C vào không gian tên chung (mặc dù nó thường xuất hiện trong triển khai C++); nó được đảm bảo để đặt chúng trong không gian tên std:

Trừ như đã nêu tại các khoản 18 đến 30 và Phụ lục D, nội dung của mỗi tiêu đề cname sẽ là tương tự như của tiêu đề tương ứng name.h, theo quy định tại thư viện chuẩn C (1.2) hoặc C Unicode TR, nếu thích hợp, như thể bao gồm. Tuy nhiên, trong thư viện chuẩn C++, các khai báo (ngoại trừ các tên được định nghĩa là các macro trong C) nằm trong phạm vi không gian tên (3.3.6) của không gian tên std. Nó không được chỉ định cho dù những tên này lần đầu tiên được khai báo trong phạm vi không gian tên toàn cầu và sau đó được tiêm vào không gian tên std bằng cách rõ ràng using -declarations (7.3.3).

(Standard, phần 17.6.1.2)

+0

thats lạ, tôi không có phạm vi atoi –

+1

@Xploit: không bao giờ nhớ bình luận trước đó của tôi.'' không đặt 'atoi' vào không gian tên' std'; nếu bạn cũng đặt nó trong không gian tên chung, thì đó là phần mở rộng dành riêng cho nền tảng. –

+0

@ larsmars Đó không phải là một tính năng, đó là một lỗi. Đó là một sự ô nhiễm không mong muốn của không gian tên toàn cầu - vốn nổi tiếng là khó để tránh làm nhà văn thư viện. gcc làm một công việc tốt để từ từ lấy ra những ô nhiễm đó. BTW, thats một trong những nguồn chính của sự đóng gói sai của các gói phần mềm với phiên bản mới hơn của gcc, mà cho đến khi sau đó biên soạn tốt. – hirschhornsalz

Các vấn đề liên quan