Đừng bao giờ viết mã như thế.
Vì j<1000
, j/1000
là 0 (chia số nguyên). Vì thế:
(&main + (&exit - &main)*(j/1000))(j+1);
tương đương với:
(&main + (&exit - &main)*0)(j+1);
Đó là:
(&main)(j+1);
Mà gọi main
với j+1
.
Nếu j == 1000
, sau đó các dòng tương tự đi ra như:
(&main + (&exit - &main)*1)(j+1);
Mà sôi xuống
(&exit)(j+1);
Đó là exit(j+1)
và rời khỏi chương trình.
(&exit)(j+1)
và exit(j+1)
về cơ bản là giống nhau - trích dẫn C99 §6.3.2.1 / 4:
Trình chỉ định hàm là một biểu thức có kiểu hàm. Ngoại trừ khi đó là toán hạng của toán tử sizeof hoặc toán tử unary & toán tử , một trình chỉ định hàm với kiểu " kiểu trả về hàm " được chuyển đổi thành một biểu thức có kiểu " con trỏ tới kiểu trả về hàm ".
exit
là một chỉ định chức năng. Ngay cả khi không có &
địa chỉ đơn vị của toán tử, nó được coi là một con trỏ để hoạt động. ( &
Chỉ làm cho nó rõ ràng.)
Và các lệnh gọi hàm được mô tả trong §6.5.2.2 / 1 và sau đây:
Biểu thức biểu thị hàm được gọi sẽ có con trỏ kiểu để hàm trả về void hoặc trả về một loại đối tượng khác với kiểu mảng.
Vì vậy, exit(j+1)
hoạt động vì chuyển đổi tự động loại chức năng thành loại con trỏ sang chức năng và (&exit)(j+1)
hoạt động tốt với chuyển đổi rõ ràng sang loại con trỏ sang chức năng.
Điều đó đang được nói, đoạn mã trên không tuân thủ ( main
có hai đối số hoặc không có gì cả), và &exit - &main
, tôi tin rằng, không được xác định theo §6.5.6 / 9:
Khi hai con trỏ bị trừ, cả hai sẽ 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ử qua phần tử cuối cùng của đối tượng mảng; ...
Bản thân phần bổ sung (&main + ...)
sẽ có giá trị và có thể được sử dụng, nếu số lượng được thêm bằng 0, vì §6.5.6 / 7 nói:
Đối với mục đích của các toán tử này, một con trỏ tới một đối tượng không phải là một phần tử của một mảng hoạt động giống như một con trỏ tới phần tử đầu tiên của một mảng có chiều dài với một loại đối tượng là kiểu phần tử của nó.
Vì vậy, thêm số 0 vào &main
sẽ ổn (nhưng không sử dụng nhiều).
main
bằng C ++.