2016-11-25 15 views
8

Tại sao biên dịch (kêu vang, gcc) không cảnh báo về chuyển đổi thu hẹp khi làm điều nàyphao khởi từ đôi với niềng răng

float a{3.1231231241234123512354123512341235123541235}; 
float a = {double(3.1231231241234123512354123512341235123541235)} 

tôi mong đợi một lời cảnh báo vì tôi làm rõ ràng giá trị khởi tạo với niềng răng. Làm theo câu trả lời này Link nó sẽ phát ra lỗi.

Compilation here

+3

afaik, nó không cảnh báo bạn nếu một giá trị chữ cụ thể có thể được biểu diễn theo loại hẹp hơn mà không mất chính xác –

+0

Điều này không biên dịch trên VS2015 (lỗi 2397) – Fefux

Trả lời

15

[dcl.init.list]/§7 (tiêu chuẩn dự thảo)

Chuyển đổi thu hẹp là một chuyển đổi ngầm

...

  • từ lâu gấp đôi để tăng gấp đôi hoặc float, hoặc từ đôi nổi, trừ trường hợp nguồn là một biểu hiện liên tục và thực tế giá trị sau khi chuyển đổi là trong phạm vi của giá trị có thể được biểu diễn (ngay cả khi nó không thể được đại diện chính xác), hoặc

...

Cả hai biểu thức 3.14159double(3.141) là các biểu thức không đổi và giá trị nằm trong phạm vi giá trị đại diện bởi float.Do đó, chuyển đổi không phải là thu hẹp như được xác định theo tiêu chuẩn và không có yêu cầu cảnh báo về chuyển đổi.


nhưng nó không đưa ra một cảnh báo còn cho đầu vào còn

Sure it does, miễn là giá trị nằm ngoài phạm vi của các giá trị biểu diễn bởi float.

10

Bởi vì nguồn là một biểu hiện liên tục và tràn không xảy ra đối với những trường hợp này, sau đó narrowing conversion lỗi sẽ không được kích hoạt.

(tôi nhấn mạnh)

chuyển đổi từ một đôi dài sẽ tăng gấp đôi hoặc nổi và chuyển đổi từ đôi nổi, trừ trường hợp nguồn là một biểu hiện liên tục và tràn không xảy ra

Nếu bạn sử dụng nó với biến số double (tức là biểu thức không liên tục) hoặc hằng số có giá trị lớn gây ra quá mức, thông báo chẩn đoán sẽ được tạo. ví dụ.

double d = 3.14159; 
float a {d}; // non-constant-expression cannot be narrowed from type 'double' to 'float' in initializer list 

EDIT (đối với đầu vào dài hơn)

Bởi vì ngay cả khi giá trị không thể được đại diện một cách chính xác bởi float, tràn vẫn không xảy ra, sau đó nó cho phép.

$8.6.4/7.2 List-initialization (tôi emphasie)

từ lâu gấp đôi để tăng gấp đôi hoặc trôi nổi, hoặc từ đôi nổi, trừ trường hợp nguồn là một biểu thức hằng số và giá trị thực tế sau khi chuyển đổi nằm trong phạm vi của các giá trị có thể được biểu diễn (ngay cả khi nó không thể được đại diện chính xác), hoặc

+1

Khi bạn nói ** phải là lỗi, không phải cảnh báo **, tôi sẽ làm rõ rằng tiêu chuẩn không yêu cầu đó là một lỗi. – user2079303

+0

@ user2079303 Tiêu chuẩn nói "chuyển đổi như vậy không được phép", vì vậy tôi nghĩ cảnh báo không phải là trường hợp, phải không? – songyuanyao

+0

bạn có quyền nhưng cũng không đưa ra cảnh báo cho các đầu vào dài hơn – Gabriel

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