Tôi đã dành nhiều ngày trong một vấn đề lạ và cuối cùng phát hiện ra rằng có hai chức năng inline
có cùng chữ ký trong dự án và chúng gây ra sự cố. Để đơn giản hóa tình hình ở đây là một ví dụ: hai cpp file:Điều gì sẽ xảy ra nếu xác định lại chức năng nội dòng?
a.cpp
#include <iostream>
void b();
inline void echo()
{
std::cout << 0 << std::endl;
}
int main()
{
echo();
b();
return 0;
}
và b.cpp
#include <iostream>
inline void echo()
{
std::cout << 1 << std::endl;
}
void b()
{
echo();
}
Xin lưu ý rằng inline
chức năng echo
có chữ ký giống nhau nhưng khác nhau thực hiện. Biên dịch và chạy
g++ a.cpp b.cpp -o a.out && ./a.out
Hoặc như thế này
g++ a.cpp -c
g++ b.cpp -c
g++ a.o b.o -o a.out
./a.out
It in 0 0
. (Tôi đã sử dụng g ++ 4.6.1 cho rằng, và tôi thử nghiệm với kêu vang ++ 2.9, cùng kết quả)
Điều đó sẽ không xảy ra nếu bật tối ưu hóa, như
g++ -O3 a.cpp b.cpp -o a.out && ./a.out
Đó là 0 1
thời gian này.
Câu hỏi của tôi là, bất kể kết quả hoặc cách biên dịch thực hiện, không có lỗi hoặc thậm chí cảnh báo về tôi đã xác định các hàm inline
nhiều lần. Điều gì trên trái đất xảy ra với trình biên dịch và mối liên kết trong tình huống như thế này?
EDIT:
Hãy nhìn vào những biểu tượng trong đối tượng tập tin
nm a.o b.o | c++filt
Cả hai file có kỷ lục echo()
. Vì vậy, tôi nghĩ rằng vấn đề xảy ra tại thời gian liên kết. Có thể nói rằng trình liên kết ngẫu nhiên chọn một triển khai và loại bỏ tất cả các cài đặt khác?
Bạn đã thử độ dài cảnh báo cao hơn (-Wall, v.v.)? – schnaader
Tôi vừa thử '-Wall -Wextra', vẫn không có cảnh báo. – neuront