Theo lời khuyên của người dùng SO đại diện, gần đây tôi đã bắt đầu biên dịch với cờ -Wconversion
trên codebase của tôi. Điều này đã tạo ra khá một vài cảnh báo, một số trong đó là hợp pháp (không cần thiết thêm signed
và unsigned
loại, ví dụ), nhưng cũng có một số scratchers đầu, chứng minh dưới đây:g ++: chuyển đổi thành uint16_t từ int có thể thay đổi giá trị
#include <cstdint>
int main()
{
uint16_t a = 4;
uint16_t b = 5;
b += a;
return 0;
}
Khi tôi biên dịch với g++ -Wconversion -std=c++11 -O0 myFile.cpp
, tôi nhận được
warning: conversion to 'uint16_t {aka short unsigned int}' from 'int' may alter its value [-Wconversion]
b += a;
^
tôi đã đọc kỹ một số câu hỏi tương tự trên SO (đối phó với |
và <<
nhà khai thác), lấy một cái nhìn here, và đã đọc Khuyến mãi Numeric và Numeric Chuyển đổi phần here. Hiểu biết của tôi là, để thực hiện phép toán, a
và b
được thăng cấp thành int
(vì đó là loại đầu tiên có thể phù hợp với toàn bộ dải giá trị uint16_t
), kết quả được viết lại, ngoại trừ kết quả của toán là int
và viết lại là uint16_t
sẽ tạo cảnh báo. Sự đồng thuận của các câu hỏi khác về cơ bản là bỏ đi cảnh báo, và cách duy nhất tôi đã tìm ra cách để làm điều đó là b = (uint16_t)(b + a);
(hoặc tương đương b = static_cast<uint16_t>(b + a);
).
Không muốn câu hỏi này để có được quá rộng, nhưng giả sử hiểu biết của tôi về chương trình khuyến mãi số nguyên là đúng ...
- cách tốt nhất để xử lý này di chuyển về phía trước là gì? Tôi có nên tránh thực hiện toán học trên các loại hẹp hơn
int
không? Nó có vẻ khá lạ với tôi rằng tôi phải đúc một kết quả số học đó là cùng loại như tất cả các toán hạng (đoán tôi mong đợi trình biên dịch để nhận ra rằng và ngăn chặn các cảnh báo). Trong lịch sử, tôi đã thích sử dụng không có nhiều bit hơn tôi cần, và chỉ để cho trình biên dịch xử lý các chương trình khuyến mãi/chuyển đổi/padding khi cần thiết. - Bất cứ ai cũng sử dụng cờ
-Wconversion
thường xuyên? Chỉ sau một vài ngày sử dụng nó bản thân mình, tôi bắt đầu nghĩ rằng trường hợp sử dụng tốt nhất của nó là để bật nó lên, nhìn vào những gì nó phàn nàn về, sửa chữa các khiếu nại hợp pháp, sau đó biến nó trở lại. Hoặc có lẽ định nghĩa của tôi về "khiếu nại hợp pháp" cần điều chỉnh lại. Thay thế tất cả các toán tử+=
của tôi với các phôi được đánh vần có vẻ như phiền toái hơn bất kỳ thứ gì.
Tôi cũng muốn gắn thẻ này là c
, vì mã tương đương c
được biên dịch với gcc -Wconversion -std=c11 -O0 myFile.c
cũng đưa ra cảnh báo tương tự. Nhưng như vậy, tôi đang sử dụng g++
phiên bản 5.3.1 trên một hộp Fedora 23 x86_64. Xin vui lòng chỉ cho tôi để các dupe nếu tôi đã bỏ lỡ nó; nếu câu trả lời/lời khuyên duy nhất ở đây là bỏ đi cảnh báo, thì đây là một bản dupe.
Nó không hoàn toàn là một sự lừa đảo, nhưng [câu trả lời này] (https://stackoverflow.com/a/39061103/1270789) xác nhận sự nghi ngờ của bạn. Tuy nhiên, cách xử lý cảnh báo '-Wconversion' chưa được trả lời, nhưng đáng để trả lời ở đây. (Và [C# thậm chí còn khó hiểu hơn] (https://stackoverflow.com/q/4343624/1270789)). –
xử lý tiếng kêu '-Wconversion' khác nhau, nó không cảnh báo cho trường hợp này. Tôi sử dụng công tắc này được bật tất cả thời gian (tôi không tắt, như bạn nói trong 2.) và tôi luôn khắc phục sự cố. Nhưng tôi hiếm khi sử dụng các loại ngắn hơn cho arithmetics. Đơn giản là không có lý do gì để sử dụng chúng. – geza
"Theo lời khuyên của một người dùng SO đại diện" - tốt, lời khuyên của tôi sẽ không sử dụng lá cờ đó bởi vì nó cho quá nhiều xác thực sai! Thành thật mà nói, tôi xem xét trường hợp trong câu hỏi của bạn là một lỗi trình biên dịch. –