Điều này là hợp pháp:
int array[5];
int *array_begin = &array[0];
int *array_end = &array[5];
Phần 5.2.1 Ký hiệu Biểu thức E1 [E2] giống hệt nhau (theo định nghĩa) với * ((E1) + (E2))
Vì vậy, chúng ta có thể nói rằng array_end cũng tương đương:
int *array_end = &(*((array) + 5));
Phần 5.3.1.1 Toán tử một ngôi '*': Toán tử một ngôi * thực hiện điều hướng: biểu thức mà nó được áp dụng sẽ là một con trỏ đến một kiểu đối tượng hoặc một con trỏ đến một kiểu hàm và kết quả là một giá trị tham chiếu đến đối tượng hoặc hàm mà biểu thức trỏ đến. Nếu kiểu của biểu thức là "con trỏ tới T", thì loại kết quả là "T." [Lưu ý: một con trỏ đến một kiểu không hoàn chỉnh (không phải cv void) có thể được tham chiếu đến. Giá trị thu được do đó có thể được sử dụng theo những cách hạn chế (để khởi tạo một tham chiếu chẳng hạn); giá trị này không được chuyển đổi thành giá trị, xem 4.1. - ghi chú cuối]
Phần quan trọng của những điều trên:
'kết quả là một giá trị tham chiếu đến đối tượng hoặc chức năng'.
Toán tử một ngôi '*' đang trả về một giá trị tham chiếu đến int (không có tham chiếu). Toán tử một ngôi '&' sau đó lấy địa chỉ của giá trị.
Miễn là không có sự hủy tham chiếu của một con trỏ ngoài giới hạn thì hoạt động được bao phủ hoàn toàn bởi tiêu chuẩn và tất cả hành vi được xác định. Vì vậy, bằng cách đọc của tôi ở trên là hoàn toàn hợp pháp.
Thực tế là rất nhiều thuật toán STL phụ thuộc vào hành vi được xác định rõ ràng, là một loại gợi ý rằng ủy ban tiêu chuẩn đã mặc dù vậy và tôi chắc chắn rằng có một cái gì đó bao gồm điều này một cách rõ ràng.
Phần bình luận dưới đây đưa ra hai lập luận:
(vui lòng đọc: nhưng nó dài và cả hai chúng tôi kết thúc trollish)
Đối số 1
điều này là bất hợp pháp vì mục 5.7 đoạn 5
Khi một biểu thức có kiểu tích phân được thêm vào hoặc trừ khỏi một con trỏ, kết quả có kiểu toán hạng con trỏ. Nếu toán hạng con trỏ trỏ đến một phần tử của một đối tượng mảng và mảng đủ lớn, thì kết quả trỏ đến một phần tử khác với phần tử ban đầu sao cho hiệu số của các chỉ số con của phần tử mảng kết quả và ban đầu bằng biểu thức tích phân. Nói cách khác, nếu biểu thức P trỏ đến phần tử thứ i của một đối tượng mảng thì các biểu thức (P) + N (tương đương, N + (P)) và (P) -N (trong đó N có giá trị n) trỏ tương ứng với các phần tử thứ i + n và i - n của đối tượng mảng, miễn là chúng tồn tại. Hơn nữa, nếu biểu thức P trỏ đến phần tử cuối cùng của một đối tượng mảng, thì biểu thức (P) +1 trỏ một điểm qua phần tử cuối cùng của đối tượng mảng, và nếu biểu thức Q trỏ qua phần tử cuối cùng của đối tượng mảng thì biểu thức (Q) -1 trỏ đến phần tử cuối cùng của đối tượng mảng. Nếu cả toán hạng con trỏ và kết quả đều trỏ đến các phần tử của cùng một đối tượng mảng hoặc một phần tử vượt qua phần tử cuối cùng của đối tượng mảng, thì phép đánh giá sẽ không tạo ra lỗi tràn; nếu không, hành vi là không xác định.
Và mặc dù phần này có liên quan; nó không hiển thị hành vi không xác định. Tất cả các phần tử trong mảng mà chúng ta đang nói đến đều nằm trong mảng hoặc nằm sau phần cuối của mảng (được xác định rõ bởi đoạn trên).
Đối số 2:
Đối số thứ hai được trình bày dưới đây là: *
là toán tử khử tham chiếu.
Và mặc dù đây là một thuật ngữ phổ biến được sử dụng để mô tả toán tử '*'; thuật ngữ này được cố ý tránh trong tiêu chuẩn vì thuật ngữ 'hủy tham chiếu' không được xác định rõ về ngôn ngữ và ý nghĩa của điều đó đối với phần cứng cơ bản.
Mặc dù việc truy cập bộ nhớ nằm ngoài phần cuối của mảng chắc chắn là hành vi không xác định. Tôi không tin rằng việc unary * operator
truy cập bộ nhớ (đọc / ghi vào bộ nhớ) trong ngữ cảnh này (không theo cách mà tiêu chuẩn xác định). Trong ngữ cảnh này (như được định nghĩa bởi tiêu chuẩn (xem 5.3.1.1))) unary * operator
trả về a lvalue referring to the object
. Theo hiểu biết của tôi về ngôn ngữ, đây không phải là quyền truy cập vào bộ nhớ cơ bản. Kết quả của biểu thức này sau đó được sử dụng ngay lập tức bởi unary & operator
toán tử trả về địa chỉ của đối tượng được tham chiếu bởi lvalue referring to the object
.
Nhiều tài liệu tham khảo khác đến Wikipedia và các nguồn không chính tắc được trình bày. Tất cả những điều đó tôi thấy không liên quan. C ++ được định nghĩa theo tiêu chuẩn .
Phần kết luận:
Tôi muốn thừa nhận rằng có nhiều phần của tiêu chuẩn mà tôi có thể đã không xem xét và có thể chứng minh những lập luận trên của tôi là sai. KHÔNG được cung cấp bên dưới. Nếu bạn cho tôi xem một tham chiếu tiêu chuẩn cho thấy đây là UB. tôi sẽ
- Để lại câu trả lời.
- Nói chung là điều này thật ngu ngốc và tôi đã sai cho tất cả mọi người khi đọc.
Đây không phải là một đối số:
Không phải mọi thứ trên toàn thế giới đều được định nghĩa bởi tiêu chuẩn C ++. Mở rộng tâm trí của bạn.