9

Trong khi sản xuất một MCVE cho this vấn đề tôi stumbled khi, tôi đã tìm thấy sự khác biệt sau đây giữa các trình biên dịch:Chuyển tiếp khai báo hàm `constexpr` bên trong một hàm khác - Lỗi trình biên dịch?

Xét đoạn mã sau:

// constexpr int f(); // 1 

constexpr int g() { 
    constexpr int f(); // 2 
    return f(); 
} 

constexpr int f() { 
    return 42; 
} 

int main() { 
    constexpr int i = g(); 
    return i; 
} 

Mã này biên dịch trên Clang 3.8.0, nhưng thất bại trên GCC 6.1.0 với:

error: 'constexpr int f()' used before its definition 

Bình luận ra // 2 và uncommenting // 1 công trình trên cả hai trình biên dịch.

Điều thú vị là, di chuyển nghĩa f 's ở vị trí của // 1 biên dịch, nhưng gây ra một cảnh báo tại // 2:

warning: inline function 'constexpr int f()' used but never defined 

nào biên dịch là đúng?

+1

Tiêu chuẩn dường như không rõ ràng về điều này. Chúng tôi cần một luật sư mạnh mẽ ở đây :) – Arunmu

Trả lời

2

Thay thế constexpr chức năng với inline chức năng giữ lại các vấn đề chính xác cùng (nó không quan trọng với việc kê khai toàn cầu 1, nhưng không phải với phần khai báo hàm-phạm vi 2.) Từ constexpr ngụ ý inline này có vẻ như là nguyên nhân.

Trong trường hợp này, với khai báo 2, GCC than phiền: warning: 'inline' specifier invalid for function 'f' declared out of global scopewarning: inline function 'int f()' used but never defined. Không thể liên kết ("undefined reference to 'f()'").

Vì vậy, có vẻ như nó từ bỏ nội tuyến, đặt trong cuộc gọi, nhưng không làm phiền mã phát ra cho f() vì tất cả các lần sử dụng đều được gạch chân (?), Do đó liên kết không thành công.

và Clang phàn nàn: error: inline declaration of 'f' not allowed in block scope

Kể từ constexpr ngụ ý inline, dường như quy định này mà khai báo inline không được phép trong phạm vi khối cũng nên áp dụng đối với constexpr, vv GCC là đúng. Nhưng tiêu chuẩn dường như không xuất hiện và nói điều này. Trong dự thảo mà tôi đã kiểm tra, quy tắc về inline là trong §7.1.2 [dcl.fct.spec], phần 3: "Trình định danh nội tuyến sẽ không xuất hiện trên khai báo hàm phạm vi khối", nhưng không có gì tương tự xuất hiện khoảng constexpr.

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