2012-01-30 31 views
13

Khi sử dụng biến thể double của hàm std::abs() mà không có std với g ++ 4.6.1, không có cảnh báo hoặc lỗi nào được đưa ra.Tránh các vấn đề về trình biên dịch với abs()

#include <algorithm> 
#include <cmath> 

double foobar(double a) 
{ 
    return abs(a); 
} 

Phiên bản này của g ++ dường như được kéo trong double biến thể của abs() vào không gian tên toàn cầu thông qua một trong những bao gồm từ algorithm. Điều này có vẻ như bây giờ được cho phép theo tiêu chuẩn (xem này question), nhưng không bắt buộc.

Nếu tôi biên dịch mã trên sử dụng một trình biên dịch mà không kéo double biến thể của abs() vào không gian tên toàn cầu (như g ++ 4.2), sau đó các lỗi sau đây được báo cáo:

warning: passing 'double' for argument 1 to 'int abs(int)' 

Làm thế nào tôi có thể force g ++ 4.6.1 và các trình biên dịch khác có chức năng kéo vào không gian tên chung, để đưa ra cảnh báo để tôi có thể ngăn lỗi khi được sử dụng với các trình biên dịch khác?

+3

Có gì sai khi sử dụng 'std :: abs' nếu đó là hàm bạn cần? –

+3

@JonathanLeffler Không có gì, nhưng có thể dễ dàng bỏ sót do nhầm lẫn. Tôi không muốn trượt đi mà không bị phát hiện và gây ra các vấn đề biên dịch với các trình biên dịch khác. –

Trả lời

8

Hàm bạn đang sử dụng thực sự là phiên bản nguyên của abs và GCC thực hiện chuyển đổi ẩn thành số nguyên.

Điều này có thể được xác nhận bởi một chương trình thử nghiệm đơn giản:

#include <iostream> 
#include <cmath> 

int main() 
{ 
    double a = -5.4321; 
    double b = std::abs(a); 
    double c = abs(a); 

    std::cout << "a = " << a << ", b = " << b << ", c = " << c << '\n'; 
} 

Output là:

 
a = -5.4321, b = 5.4321, c = 5 

Để có được một cảnh báo về vấn đề này, sử dụng -Wconversion cờ để g ++. Trên thực tế, tài liệu GCC cho tùy chọn đó đề cập rõ ràng việc gọi số abs khi đối số là double. Tất cả các tùy chọn cảnh báo có thể được tìm thấy here.

+0

Mã mẫu không khớp với đầu ra. –

+0

@SamDeHaan Xin lỗi, cập nhật kết quả nhưng quên cập nhật mã. :) –

+0

Đây có phải là tiêu chuẩn đã thay đổi hoặc thay đổi trong việc thực hiện của g ++ gây ra chuyển đổi tiềm ẩn với 4.6.1 và không 4.2? Cả hai đều hợp lệ? –

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