2015-07-26 14 views
8

Tôi có một dự án C++ mà tôi biên dịch cả bằng cách sử dụng g++ trên máy của mình (biên dịch thành "máy chủ") và bộ xử lý ARM sử dụng trình biên dịch chéo (trong trường hợp của tôi là arm-cortex_a8-linux-gnueabi-g++). Tôi đang trong quá trình chuyển đổi sang C++ 0x/11 standart và có một lỗi tôi nhận được khi biên soạn danh sách khởi tạo, mà tôi đã có thể sinh sản trong đoạn mã sau:"Thu hẹp chuyển đổi từ 'int' thành 'char' bên trong {}" cho các giá trị pháp lý khi biên dịch

int main(void) { 
    char c[1] = {-108}; 
} 

Chương trình này là dường như đúng như -108 là một giá trị pháp lý cho một char. Biên dịch này với g++ mang lại không có lỗi với dòng lệnh sau đây:

g++ example.cc -std=c++0x 

Tuy nhiên, khi tôi biên dịch với cross-biên dịch, như vậy:

arm-cortex_a8-linux-gnueabi-g++ example.cc -std=c++0x 

tôi nhận được lỗi sau:

example.cc: In function 'int main()': 
example.cc:2:22: error: narrowing conversion of '-0x0000000000000006c' from 'int' to 'char' inside { } [-fpermissive] 

Kể từ khi giá trị pháp lý, điều này có vẻ như một lỗi. Bạn có thể giải thích tại sao tôi nhận được lỗi này và phải làm gì để giải quyết nó?

Chỉnh sửa: lưu ý rằng việc sử dụng giá trị dương (ví dụ: 108) là hợp pháp và không dẫn đến lỗi trên cả hai trình biên dịch.

+0

'char' có thể là unsigned trên nền tảng mục tiêu. Bạn có thể kiểm tra? – Brian

+0

@Brian, làm cách nào để kiểm tra? –

+0

@AndyThomas 'std :: is_signed '? Hoặc, rỉ sét, 'char (-1) <'\ 0'' – Columbo

Trả lời

14

Khi bạn khai báo một biến như char, đó là thực hiện phụ thuộc cho dù đó là ký kết hoặc unsigned. Nếu bạn cần để có thể lưu trữ các giá trị âm, bạn nên khai báo nó signed một cách rõ ràng, chứ không phải dựa vào mặc định thực hiện xác định.

signed char c[1] = { -108 }; 
9

Since the value is legal

Làm thế nào để bạn biết điều đó? char s signness được thực hiện xác định. Và nếu đó là unsigned, mã của bạn là vô hình thành bởi hẹp - §8.5.4/7:

A narrowing conversion is an implicit conversion
[…]
(7.4) — from an integer type […] to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.

§8.5.1/2:

If the initializer-clause is an expression and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed.

Tuy nhiên, nếu bạn cần một ký char , sử dụng signed char.

signed char c[1] = {-108}; 

… được đảm bảo hoạt động.

-1

này nên được thậm chí tốt hơn:

signed char c[] = { (signed char)(-108) }; 

Bởi vì trong ngoặc đơn giá trị có thể được coi là int theo mặc định.

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