Mẫu hành vi không xác định ngắn nhất trong C ++ [đã đóng]


8

Mã C ++ ngắn nhất, được hình thành tốt nhất thể hiện hành vi không xác định là gì?


1
Bạn có nghĩa là "runnable" là gì? Nếu nó có UB, không có gì đảm bảo nó có thể chạy được.
R. Martinho Fernandes

@ R.MartinhoFernandes tốt, ý tôi là nó bắt đầu.
Luchian Grigore

@LuchianGrigore rất phụ thuộc vào trình biên dịch (phiên bản).
rubenvb

1
Xác định "tang vật". Có cần phải thể hiện một cái gì đó? Hoặc là nó đủ để trạng thái bộ nhớ trong không được xác định tại một số điểm trong chương trình?
Ông Lister

Câu trả lời:


12
int main(){main;}

3.6.1 Hàm chính [basic.start.main]

3 - [...] Chức năng chính sẽ không được sử dụng trong một chương trình.

Chỉnh sửa: đây là chẩn đoán, vì vậy không phải là UB.


int main(){for(;;);}

1.10 Thực thi đa luồng và các cuộc đua dữ liệu [intro.multithread]

24 - Việc triển khai có thể giả định rằng bất kỳ luồng nào cuối cùng cũng sẽ thực hiện một trong các thao tác sau: - chấm dứt, - thực hiện cuộc gọi đến chức năng I / O của thư viện, - truy cập hoặc sửa đổi một đối tượng dễ bay hơi hoặc - thực hiện thao tác đồng bộ hóa hoặc hoạt động nguyên tử .


int main(){int i=i;}

4.1 Chuyển đổi Lvalue-to-rvalue [conv.lval]

1 - [...] Nếu đối tượng mà glvalue đề cập là [...] chưa được khởi tạo, một chương trình yêu cầu chuyển đổi này có hành vi chưa được thực hiện.


//^L.

Đây ^Llà ký tự nguồn cấp mẫu, là một phần của bộ ký tự cơ bản. 4 ký tự (không cần một dòng mới cho mỗi 2.2: 2). Hành vi không xác định là trên mỗi

2.8 Nhận xét [lex.comment]

1 - Nếu có một nguồn cấp dữ liệu biểu mẫu hoặc ký tự tab dọc trong //nhận xét [a -style], chỉ các ký tự khoảng trắng sẽ xuất hiện giữa nó và dòng mới chấm dứt nhận xét; không cần chẩn đoán.


cái thứ hai không xác định. Nó có thể tối ưu hóa vòng lặp for mà không có vấn đề. Đó không phải là hành vi không xác định.
rubenvb

3
@rubenvb stackoverflow.com/questions/3592557/... - bất cứ lúc nào tiêu chuẩn nói "trình biên dịch có thể giả định P," nó được ngụ ý rằng một chương trình trong đó có bất động sản không-P có ngữ nghĩa không xác định .
ecatmur

Tuy nhiên, trình biên dịch cũng có thể giả sử không có tác dụng phụ khi tạo ra các hàm tạo sao chép.
rubenvb

@rubenvb vì trường hợp cụ thể đó được đề cập rõ ràng .
R. Martinho Fernandes

1
@BogdanAlexandru dự án nhúng của bạn có hành vi không xác định. Điều đó có nghĩa là nó có thể hoạt động như bạn mong đợi bây giờ, nhưng khi bạn nâng cấp trình biên dịch, nó sẽ hoạt động khác đi.
ecatmur

5
\u\
0000

Điều này có tám ký tự và có hành vi không xác định, theo §2.2 / 1.

Mỗi phiên bản của một ký tự dấu gạch chéo ngược ( \) ngay sau đó là một ký tự dòng mới sẽ bị xóa, nối các dòng nguồn vật lý để tạo thành các dòng nguồn logic. Chỉ dấu gạch chéo ngược cuối cùng trên bất kỳ dòng nguồn vật lý nào mới đủ điều kiện trở thành một phần của mối nối đó. Nếu, do đó, một chuỗi ký tự khớp với cú pháp của tên ký tự phổ quát được tạo ra, hành vi không được xác định.


đây không phải là & "chương trình". Một chương trình có một main.
rubenvb

@rubenvb Hãy thử nó trên Hell ++. Nó có hành vi không xác định, vì vậy có thể là một chương trình mà không có a main. Thật khó để thực thi các quy tắc khi bạn yêu cầu một chương trình không có bất kỳ quy tắc nào phải tuân theo (đó là ý nghĩa của UB!).
R. Martinho Fernandes

3
Dựa trên cách diễn đạt của câu hỏi, tôi nghĩ rằng điều này đủ điều kiện - nó chỉ yêu cầu "mã" ngắn nhất hiển thị UB. Dựa trên "runnable" trong bình luận, tôi nghĩ rằng ý định, tuy nhiên, là chương trình ngắn nhất , sẽ loại trừ mã của bạn, bởi vì theo §3.6.1 / 1: "Một chương trình sẽ chứa một hàm toàn cầu được gọi là chính, đó là sự khởi đầu được chỉ định của chương trình. " Như vậy, không có main, những gì bạn có là không đúng.
Jerry Coffin

1
@JerryCoffin Anh ấy đang sử dụng một môi trường độc lập mà không yêu cầu chính. Bạn thuận tiện bỏ đi phần còn lại của §3.6.1 / 1 có nội dung "Nó được xác định theo triển khai cho dù chương trình trong môi trường tự do là bắt buộc để xác định chức năng chính.". Đây là một chương trình hợp lệ ("hợp lệ" như trong "chương trình" theo lập luận của bạn).
David

Dang, chỉ cần đến đây để mang cái đó. +1
Columbo

2
#include. /*Imagine a new-line right after the dot*/

§16.2 / 4:

Một chỉ thị tiền xử lý của mẫu

             #include  pp-tokens dòng mới

(không phù hợp với một trong hai hình thức trước đó) được cho phép. [..] Nếu chỉ thị dẫn đến sau tất cả các thay thế không khớp với một trong hai hình thức trước đó, thì hành vi không được xác định.


Sẽ không phân tích tương tự nếu bạn loại bỏ khoảng trắng trước dấu chấm?
frageum

@feersum Yep. Điều đó không làm thay đổi ý tưởng, đó là lý do tại sao tôi tránh nó để tăng cường khả năng đọc, nhưng tôi đoán nó phục vụ cho điểm của câu hỏi để minh họa rằng không gian có thể được bỏ qua. Cảm ơn!
Columbo

2
int main(){int i=1>>-1;}

Giải trình:

C ++ 98 và C ++ 11 §5.8 / 1 đều nói rằng

Hành vi không được xác định nếu toán hạng bên phải âm hoặc lớn hơn hoặc bằng độ dài tính bằng bit của toán hạng bên trái được thăng cấp.


3
trên hệ thống 32 bit, không phải độ dài tính bằng bit intthường là 32? thay đổi RHS của sự thay đổi thành -1cùng số lượng ký tự và sẽ không phụ thuộc vào kích thước số nguyên
ardew

1

Nếu ai đó tin wikipedia, thì đây là một vài:

Sửa đổi chuỗi được cho là gây ra hành vi không xác định. Nó luôn làm việc cho tôi.

int main(int c,char*v){v[0]='.';}

Hàm không rỗng không có trả về gây ra các giá trị trả về không xác định.

int a(){}
int main(){return a();}

Phân chia (của int?) Bằng 0 được cho là không xác định. Tất cả những gì tôi biết là nó gặp sự cố.

int main(int c){c/0;}

Đây không phải là đoạn mã hợp pháp. Chính phải được định nghĩa là int main(){}ít nhất.
rubenvb

Chết tiệt, tôi chắc chắn câu hỏi là về C. Xin lỗi về điều đó.
shiona

1
@shiona tham số thứ hai nên char **không char *. Bạn chỉ đang sửa đổi một phần của giá trị con trỏ. Trong thực tế, argvđược đảm bảo để có thể sửa đổi một cách an toàn.
oldrinb

Tiêu chuẩn cho phép chuỗi ký tự ở dạng chỉ đọc, vì vậy nhiều triển khai thực hiện điều đó. Đó là chính xác char *argv[]để không có bất kỳ constvòng loại. Bạn có thể gặp sự cố bằng cách viết thành một chuỗi ký tự bằngint main(){char *v="";*v=1;}
Peter Cordes

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.