Có thực sự là hai phần cho câu hỏi này, là hỏi:
một biến thể được sử dụng trong khi được công bố?
nơi có câu trả lời rõ ràng là Có, do nguyên tắc khai báo được trích dẫn trong các câu trả lời khác.
Và, quan trọng không kém nhưng không hỏi:
gì tập quán của một biến trong khai của nó là an toàn không?
Vâng, trong bộ khởi tạo, biến chưa hoàn thành khởi tạo (một vấn đề về tuổi thọ đối tượng), và trong thực tế, xây dựng vẫn chưa bắt đầu. Các quy tắc đối tượng suốt đời (phần 3.8 của tiêu chuẩn) phát biểu rằng một số nhưng không phải tất cả các hoạt động được phép trên một biến như:
Trước khi cuộc đời của một đối tượng đã bắt đầu nhưng sau khi lưu trữ trong đó đối tượng sẽ chiếm đã được được cấp phát hoặc sau khi thời gian tồn tại của đối tượng đã kết thúc và trước khi lưu trữ đối tượng bị chiếm dụng hoặc được giải phóng, bất kỳ con trỏ nào trỏ đến vị trí lưu trữ nơi đối tượng sẽ được định vị hoặc chỉ có thể được sử dụng nhưng chỉ theo những cách hạn chế. Đối với một đối tượng đang được xây dựng hoặc phá hủy, xem 12.7. Nếu không, con trỏ như vậy đề cập đến bộ nhớ được phân bổ và sử dụng con trỏ như thể con trỏ thuộc loại void*
, được xác định rõ. Việc chuyển hướng thông qua con trỏ như vậy được cho phép nhưng giá trị kết quả chỉ có thể được sử dụng theo những cách hạn chế, như được mô tả bên dưới.Chương trình này đã không xác định hành vi nếu:
- đối tượng sẽ được hoặc là của một loại lớp học với một destructor không tầm thường và con trỏ được sử dụng như là toán hạng của một delete-ngôn luận,
- con trỏ được sử dụng để truy cập thành viên dữ liệu không tĩnh hoặc gọi hàm thành viên không tĩnh của đối tượng hoặc
- con trỏ được chuyển đổi hoàn toàn thành con trỏ đến lớp cơ sở ảo hoặc
- con trỏ được sử dụng làm toán hạng a
static_cast
, ngoại trừ khi chuyển đổi là trỏ đến cv
void
, hoặc để con trỏ đến cv
void
và sau đó để con trỏ đến một trong hai cv
char
hoặc cv
unsigned char
, hoặc
- con trỏ được sử dụng như là toán hạng của một
dynamic_cast
.
có hiệu quả, với nhiều loại với khởi tạo không tầm thường, vị trí bộ nhớ không chứa một đối tượng, vì vậy nó không có loại năng động, và cố gắng truy cập nó như bất kỳ loại trừ char
hoặc unsigned char
ngay lập tức rơi afoul của bí danh nghiêm ngặt.
Đối với các loại có khởi tạo nhỏ, bao gồm int
, một đối tượng tồn tại ngay sau khi lưu trữ được căn chỉnh phù hợp. Nhưng nếu bộ nhớ đó có thời lượng lưu trữ tự động hoặc động, giá trị sẽ không xác định cho đến khi biến được ghi vào. Quy tắc này từ mục 8.5 áp dụng:
Nếu không có bộ khởi tạo nào được chỉ định cho đối tượng, đối tượng được khởi tạo mặc định. Khi lưu trữ cho một đối tượng có thời lượng lưu trữ tự động hoặc động, đối tượng có giá trị không xác định và nếu không có khởi tạo được thực hiện cho đối tượng, đối tượng đó giữ lại giá trị không xác định cho đến khi giá trị đó được thay thế. [Lưu ý: Các đối tượng có thời gian lưu trữ tĩnh hoặc luồng không được khởi tạo, xem 3.6.2. - cuối note] Nếu một giá trị không xác định được sản xuất bởi một thẩm định, hành vi đó là undefined trừ trong các trường hợp sau đây:
và tất cả các trường hợp ngoại lệ được liệt kê là đặc trưng cho unsigned char
.
Thoạt nhìn, quy tắc này dường như không áp dụng, bởi vì trình khởi tạo được chỉ định. Tuy nhiên, trong quá trình đánh giá bộ khởi tạo, chúng tôi chính xác trong trường hợp "Khi lưu trữ cho một đối tượng có thời lượng lưu trữ tự động hoặc động được thu được" trong đó quy tắc áp dụng.
Bạn có thích câu trả lời cho C++ hoặc cho c? Có thể chúng khác nhau, xem xét chúng có các tiêu chuẩn khác nhau. – horns
Đó là hành vi không xác định. – Maroun
Một lý do chính đáng nữa để bật cảnh báo trình biên dịch: '-Wall -Werror' là bạn của bạn. – chqrlie