Các mã sau đây gây nên C4345 trên dòng rõ rệt:Cảnh báo C4345 của Visual Studio có sai không?
#include <array>
#include <iostream>
int main(){
static unsigned const buf_size = 5;
typedef std::array<char, buf_size> buf_type;
char buf[] = { 5, 5, 5, 5, 5 };
void* p = &buf[0];
buf_type* pbuf = new (p) buf_type(); // <=== #10
for(unsigned i=0; i < buf_size; ++i)
std::cout << (char)((*pbuf)[i] + 0x30) << ' ';
}
main.cpp (10): cảnh báo C4345: thay đổi hành vi: một đối tượng kiểu POD được xây dựng với một initializer có dạng() sẽ được mặc định khởi tạo
vì vậy, theo cảnh báo của họ, dòng 10 nên có hành vi tương tự như thể nó đã được viết như
buf_type* pbuf = new (p) buf_type; // note the missing '()'
Tuy nhiên, đầu ra khác nhau. Cụ thể, phiên bản đầu tiên sẽ in năm 0
s, trong khi phiên bản thứ hai sẽ in năm 5
s. Như vậy, phiên bản đầu tiên thực sự là giá trị khởi tạo (và bộ đệm cơ bản zero-initialized), mặc dù MSVC nói rằng nó sẽ không.
Đây có phải là lỗi trong MSVC không? Hoặc tôi đã giải thích sai sự cảnh báo/mã lỗi của tôi có bị lỗi không?
¤ Cảnh báo đề cập đến việc thiếu khởi tạo trong các phiên bản cũ hơn, tức là cảnh báo, Cảnh báo, CẢNH BÁO !, chúng tôi đã khắc phục lỗi trước đó! Trích dẫn tiêu chuẩn thánh: "Một đối tượng có bộ khởi tạo là một bộ ngoặc đơn trống, tức là,(), sẽ được khởi tạo giá trị", trong trường hợp không có khởi tạo được chỉ định cho một cái gì đó được chuyển thành không khởi tạo. Cảnh báo, tuy nhiên, không chính xác đề cập đến "khởi tạo mặc định" (không chính xác trừ khi vẫn còn một lỗi). Đó có thể là lý do tại sao các câu trả lời ở đây cho đến nay đã được khá bối rối. Chúc mừng & hth., –