Ngoài các vấn đề về truy cập thông qua con trỏ NULL, có một vấn đề tế nhị trong các mã
$ 9.4.2/2 - "Việc kê khai của một thành viên dữ liệu tĩnh trong định nghĩa lớp của nó không phải là một định nghĩa và có thể là một loại không đầy đủ khác với khoảng trống đủ điều kiện cv. Định nghĩa cho một thành viên dữ liệu tĩnh sẽ xuất hiện trong một phạm vi không gian tên kèm theo định nghĩa lớp của thành viên. "
$ 9.4.2/4- "Nếu một thành viên dữ liệu tĩnh có dạng tách rời hoặc kiểu liệt kê, khai báo của nó trong định nghĩa lớp có thể chỉ định bộ khởi tạo không đổi sẽ là biểu thức hằng số không thể tách rời (5.19). trường hợp, thành viên có thể xuất hiện trong các biểu thức hằng số tích phân. Thành viên vẫn phải được xác định trong phạm vi không gian tên nếu nó được sử dụng trong chương trình và định nghĩa phạm vi không gian tên không chứa bộ khởi tạo. "
class Foo {
public:
static const int kType = 42;
};
int const Foo::kType;
void Func() {
Foo *bar = NULL;
int x = bar->kType;
putc(x, stderr);
}
Vì vậy, một lý do nữa cho UB trong mã OP.
Hầu hết các trình biên dịch sẽ cho bạn một cảnh báo về việc truy cập các thành viên static/const thông qua một con trỏ cá thể. – cHao