Là 'int main;' một chương trình C / C ++ hợp lệ?


113

Tôi hỏi vì trình biên dịch của tôi dường như nghĩ vậy, mặc dù tôi không nghĩ như vậy.

echo 'int main;' | cc -x c - -Wall
echo 'int main;' | c++ -x c++ - -Wall

Clang không đưa ra cảnh báo hoặc lỗi nào với điều này và gcc chỉ đưa ra cảnh báo bình thường:, 'main' is usually a function [-Wmain]nhưng chỉ khi được biên dịch thành C. Việc chỉ định a -std=dường như không quan trọng.

Nếu không, nó biên dịch và liên kết tốt. Nhưng khi thực thi, nó kết thúc ngay lập tức với SIGBUS(đối với tôi).

Đọc qua các câu trả lời (xuất sắc) tại Hàm main () trả về trong C và C ++ là gì? và một grep nhanh chóng thông qua các thông số kỹ thuật ngôn ngữ, chắc chắn nó sẽ có vẻ với tôi rằng một chính chức năng là bắt buộc. Nhưng chi tiết từ gcc's -Wmain('main' thường là một hàm) (và rất ít lỗi ở đây) dường như có thể gợi ý khác.

Nhưng tại sao? Có một số trường hợp cạnh kỳ lạ hoặc sử dụng "lịch sử" cho việc này không? Bất cứ ai biết những gì cho?

Tôi cho rằng quan điểm của tôi là tôi thực sự nghĩ rằng đây phải là một lỗi trong môi trường được lưu trữ, phải không?


6
Để làm cho gcc một (chủ yếu) biên dịch phù hợp tiêu chuẩn mà bạn cầngcc -std=c99 -pedantic ...
PMG

3
@pmg Cảnh báo tương tự, có hoặc không -pedantichoặc bất kỳ -std. Hệ thống của tôi c99cũng biên dịch này mà không có cảnh báo hoặc lỗi ...
Geoff Nixon

3
Thật không may, nếu bạn "đủ thông minh", bạn có thể tạo ra những thứ được trình biên dịch chấp nhận nhưng không có ý nghĩa. Trong trường hợp này, bạn đang liên kết thư viện thời gian chạy C để gọi một biến được gọi main, biến này không có khả năng hoạt động. Nếu bạn khởi tạo main với giá trị "right", nó có thể thực sự trả về ...
Mats Petersson

7
Và ngay cả khi nó hợp lệ, đó là một điều tồi tệ để làm (mã không thể đọc được). BTW, nó có thể là khác nhau trong việc triển khai tổ chức và trong việc triển khai miễn phí-đứng (mà không biết về main)
Basile Starynkevitch

1
Đối với lần vui vẻ hơn, hãy thửmain=195;
imallett

Câu trả lời:


97

Vì câu hỏi được gắn thẻ kép là C và C ++ nên lý do cho C ++ và C sẽ khác nhau:

  • C ++ sử dụng chức năng quản lý tên để giúp trình liên kết phân biệt giữa các ký hiệu giống nhau về văn bản của các kiểu khác nhau, ví dụ như một biến toàn cục xyzvà một hàm toàn cục độc lập xyz(int). Tuy nhiên, cái tên mainkhông bao giờ bị lệch.
  • C không sử dụng mangling, vì vậy chương trình có thể gây nhầm lẫn cho trình liên kết bằng cách cung cấp một ký hiệu của một loại thay cho một ký hiệu khác, và chương trình đã liên kết thành công.

Đó là những gì đang diễn ra ở đây: trình liên kết mong đợi tìm thấy biểu tượng mainvà nó đã làm được. Nó "dây" biểu tượng đó như thể nó là một hàm, bởi vì nó không biết gì tốt hơn. Phần thư viện thời gian chạy chuyển quyền kiểm soát để mainyêu cầu trình liên kết main, vì vậy trình liên kết cung cấp cho nó biểu tượng main, để cho giai đoạn liên kết hoàn thành. Tất nhiên điều này không thành công trong thời gian chạy, vì mainkhông phải là một chức năng.

Đây là một minh họa khác về vấn đề tương tự:

tệp xc:

#include <stdio.h>
int foo(); // <<== main() expects this
int main(){
    printf("%p\n", (void*)&foo);
    return 0;
}

tệp yc:

int foo; // <<== external definition supplies a symbol of a wrong kind

biên dịch:

gcc x.c y.c

Điều này biên dịch và nó có thể sẽ chạy, nhưng đó là hành vi không xác định, bởi vì loại ký hiệu được hứa với trình biên dịch khác với ký hiệu thực tế được cung cấp cho trình liên kết.

Theo như cảnh báo, tôi nghĩ là hợp lý: C cho phép bạn xây dựng các thư viện không có mainchức năng, vì vậy trình biên dịch giải phóng tên maincho các mục đích sử dụng khác nếu bạn cần xác định một biến mainvì một số lý do không xác định.


3
Mặc dù vậy, trình biên dịch C ++ xử lý chức năng chính khác nhau. Tên của nó không bị lệch ngay cả khi không có chữ "C" bên ngoài. Tôi đoán đó là vì nếu không nó sẽ cần phải phát ra chính "C" bên ngoài của riêng nó, để đảm bảo liên kết.
UldisK

@UldisK Vâng, bản thân tôi cũng nhận thấy điều này và thấy khá thú vị. Nó có lý, nhưng tôi chưa bao giờ nghĩ về điều đó.
Geoff Nixon

2
Trên thực tế, kết quả cho C ++ và C không khác nhau, như đã chỉ ra ở đây - mainkhông phụ thuộc vào việc đặt tên (vì vậy có vẻ như) trong C ++, cho dù nó có phải là một hàm hay không.
Geoff Nixon

4
@nm Tôi nghĩ rằng cách giải thích của bạn về câu hỏi quá hạn hẹp: ngoài việc đặt câu hỏi trong tiêu đề của bài đăng, OP rõ ràng còn tìm kiếm lời giải thích tại sao chương trình của anh ấy được biên dịch ngay từ đầu ("trình biên dịch của tôi dường như nghĩ vậy, mặc dù tôi không ") cũng như gợi ý về lý do tại sao nó có thể hữu ích khi định nghĩa mainlà bất kỳ thứ gì khác ngoài một hàm. Câu trả lời đưa ra lời giải thích cho cả hai phần.
dasblinkenlight

1
Việc biểu tượng chính không phải là tên mangling là không liên quan. Không có đề cập đến việc xáo trộn tên trong tiêu chuẩn C ++. Mangling tên là một vấn đề triển khai.
David Hammen

30

mainkhông phải là một từ dành riêng nó chỉ là một định danh được xác định trước (như cin, endl, npos...), do đó bạn có thể khai báo một biến gọi là main, khởi tạo nó và sau đó in ra giá trị của nó.

Tất nhiên:

  • cảnh báo rất hữu ích vì điều này khá dễ xảy ra lỗi;
  • bạn có thể có tệp nguồn mà không có main()chức năng (thư viện).

BIÊN TẬP

Một số tài liệu tham khảo:

  • main không phải là một từ dành riêng (C ++ 11):

    Chức năng này mainsẽ không được sử dụng trong một chương trình. Mối liên kết (3.5) của mainđược xác định thực thi. Một chương trình định nghĩa chính như xóa hoặc tuyên bố chính là inline, statichoặc constexprlà vô hình thành. Tên mainnày không được bảo lưu. [Ví dụ: các hàm thành viên, lớp và kiểu liệt kê có thể được gọi main, cũng như các thực thể trong không gian tên khác. - cuối ví dụ]

    C ++ 11 - [basic.start.main] 3.6.1.3

    [2.11 / 3] [...] một số định danh được dành riêng cho việc triển khai C ++ và thư viện tiêu chuẩn (17.6.4.3.2) và sẽ không được sử dụng theo cách khác; không cần chẩn đoán.

    [17.6.4.3.2 / 1] Một số bộ tên và chữ ký hàm nhất định luôn được dành riêng cho việc triển khai:

    • Mỗi tên chứa dấu gạch dưới kép __ hoặc bắt đầu bằng dấu gạch dưới theo sau là chữ hoa (2.12) được dành riêng cho việc triển khai cho mọi mục đích sử dụng.
    • Mỗi tên bắt đầu bằng dấu gạch dưới được dành riêng cho việc triển khai để sử dụng làm tên trong không gian tên chung.
  • Các từ dành riêng trong ngôn ngữ lập trình .

    Các từ dành riêng có thể không được lập trình viên xác định lại, nhưng các từ định nghĩa trước thường có thể bị ghi đè ở một số dung lượng. Đây là trường hợp của main: có những phạm vi trong đó một khai báo sử dụng số nhận dạng đó xác định lại ý nghĩa của nó.


- Tôi đoán tôi là thay vì gạt bởi thực tế là (vì nó rất dễ bị lỗi), tại sao điều này là một cảnh báo (không phải là một lỗi), và tại sao nó chỉ là một cảnh báo khi biên dịch như C - Chắc chắn, bạn có thể biên dịch mà không một main()chức năng, nhưng bạn không thể liên kết nó như một chương trình. Điều đang xảy ra ở đây là một chương trình "hợp lệ" đang được liên kết mà không có main(), chỉ là a main.
Geoff Nixon

7
cinendlkhông nằm trong vùng tên mặc định - chúng nằm trong vùng stdtên. nposlà một thành viên của std::basic_string.
AnotherParker

1
main được đặt dưới dạng tên toàn cầu. Không có điều nào khác mà bạn đã đề cập, và cũng không mainđược xác định trước.
Potatoswatter

1
Xem C ++ 14 §3.6.1 và C11 §5.1.2.2.1 để biết các giới hạn về những gì mainđược phép. C ++ nói "Việc triển khai sẽ không xác định trước hàm chính" và C nói "Việc triển khai không khai báo nguyên mẫu nào cho hàm này."
Potatoswatter

@manlio: vui lòng làm rõ những gì bạn đang trích dẫn. Đối với C đơn giản, trích dẫn là sai. Vì vậy, tôi đoán nó là bất kỳ tiêu chuẩn c ++ nào phải không?
dhein

19

int main;một C C ++ chương trình / hợp lệ?

Không hoàn toàn rõ ràng chương trình C / C ++ là gì.

int main;một chương trình C hợp lệ?

Đúng. Triển khai tự do được phép chấp nhận chương trình như vậy. mainkhông cần phải có bất kỳ ý nghĩa đặc biệt nào trong môi trường tự do.

không hợp lệ trong môi trường được lưu trữ.

int main;một chương trình hợp lệ C ++?

Như trên.

Tại sao nó bị rơi?

Chương trình không nhất thiết phải có ý nghĩa trong môi trường của bạn . Trong một môi trường tự do, việc khởi động và kết thúc chương trình và ý nghĩa của mainnó là do việc triển khai xác định.

Tại sao trình biên dịch cảnh báo tôi?

Trình biên dịch có thể cảnh báo bạn về bất cứ điều gì nó hài lòng, miễn là nó không từ chối các chương trình phù hợp. Mặt khác, cảnh báo là tất cả những gì cần thiết để chẩn đoán một chương trình không phù hợp. Vì đơn vị dịch này không thể là một phần của chương trình được lưu trữ hợp lệ, nên thông báo chẩn đoán là hợp lý.

gccmôi trường tự do hay môi trường được lưu trữ?

Đúng.

gcctài liệu -ffreestandingcờ biên dịch. Thêm nó và cảnh báo biến mất. Bạn có thể muốn sử dụng nó khi xây dựng, ví dụ như hạt nhân hoặc phần sụn.

g++không ghi lại cờ như vậy. Cung cấp nó dường như không ảnh hưởng đến chương trình này. Có thể an toàn khi giả định rằng môi trường do g ++ cung cấp được lưu trữ. Sự vắng mặt của chẩn đoán trong trường hợp này là một lỗi.


17

Đó là một cảnh báo vì nó không được phép về mặt kỹ thuật. Mã khởi động sẽ sử dụng vị trí ký hiệu của "main" và chuyển đến nó với ba đối số tiêu chuẩn (argc, argv và envp). Nó không, và tại thời điểm liên kết không thể kiểm tra xem nó có thực sự là một hàm hay không, thậm chí nó có các đối số đó. Đây cũng là lý do tại sao int main (int argc, char ** argv) hoạt động - trình biên dịch không biết về đối số envp và nó chỉ xảy ra là không được sử dụng, và nó là người gọi-dọn dẹp.

Như một trò đùa, bạn có thể làm điều gì đó như

int main = 0xCBCBCBCB;

trên máy x86 và, bỏ qua các cảnh báo và những thứ tương tự, nó sẽ không chỉ biên dịch mà còn thực sự hoạt động.

Ai đó đã sử dụng một kỹ thuật tương tự như kỹ thuật này để viết một tệp thực thi (loại) chạy trực tiếp trên nhiều kiến ​​trúc - http://phrack.org/issues/57/17.html#article . Nó cũng được sử dụng để giành chiến thắng trong IOCCC - http://www.ioccc.org/1984/mullender/mullender.c .


1
"Đó là một cảnh báo vì nó không được phép về mặt kỹ thuật" - nó không hợp lệ trong C ++.
Chúc mừng và hth. - Alf

3
"ba đối số tiêu chuẩn (argc, argv và envp)" - ở đây bạn có thể đang nói về tiêu chuẩn Posix.
Chúc mừng và hth. - Alf

Trên hệ thống của tôi (Ubuntu 14 / x64), dòng sau làm việc với gcc:int main __attribute__ ((section (".text")))= 0xC3C3C3C3;
csharpfolk

@ Cheersandhth.-Alf Hai cái đầu tiên là tiêu chuẩn, cái thứ ba là POSIX.
dascandy

9

Nó có phải là một chương trình hợp lệ?

Không.

Nó không phải là một chương trình vì nó không có phần thực thi.

Nó có hợp lệ để biên dịch không?

Đúng.

Nó có thể được sử dụng với một chương trình hợp lệ?

Đúng.

Không phải tất cả mã đã biên dịch đều được yêu cầu phải có thể thực thi để hợp lệ. Ví dụ là các thư viện tĩnh và động.

Bạn đã xây dựng một cách hiệu quả một tệp đối tượng. Nó không phải là một tệp thực thi hợp lệ, tuy nhiên một chương trình khác có thể liên kết đến đối tượng maintrong tệp kết quả bằng cách tải nó trong thời gian chạy.

Đây có phải là một lỗi?

Theo truyền thống, C ++ cho phép người dùng làm những việc có vẻ như không có giá trị sử dụng nhưng phù hợp với cú pháp của ngôn ngữ.

Ý tôi là chắc chắn, điều này có thể được phân loại lại là một lỗi, nhưng tại sao? Mục đích nào mà cảnh báo không phục vụ?

Vì vậy, miễn là có khả năng lý thuyết về chức năng này được sử dụng trong mã thực tế, thì việc một đối tượng không phải chức năng được gọi là mainrất có thể dẫn đến lỗi theo ngôn ngữ.


Nó tạo ra một biểu tượng có thể nhìn thấy bên ngoài được đặt tên main. Làm thế nào một chương trình hợp lệ, phải có một chức năng hiển thị bên ngoài được đặt tên main, có thể liên kết với nó?
Keith Thompson

@KeithThompson Tải trong thời gian chạy. Sẽ làm rõ.
Michael Gazonda

Nó có thể vì nó không thể phân biệt được sự khác biệt giữa các loại ký hiệu. Việc liên kết hoạt động tốt - thực hiện (trừ trường hợp được chế tạo cẩn thận) thì không.
Chris Stratton

1
@ChrisStratton: Tôi nghĩ lập luận của Keith là liên kết không thành công vì biểu tượng được nhân được xác định ... bởi vì "chương trình hợp lệ" sẽ không phải là chương trình hợp lệ trừ khi nó định nghĩa một mainhàm.
Ben Voigt

@BenVoigt Nhưng nếu nó xuất hiện trong thư viện, thì liên kết sẽ không (và có lẽ không thể) không thành công, bởi vì tại thời điểm liên kết chương trình, int main;định nghĩa sẽ không hiển thị.

6

Tôi muốn thêm vào các câu trả lời đã được đưa ra bằng cách trích dẫn các tiêu chuẩn ngôn ngữ thực tế.

Là 'int main;' một chương trình C hợp lệ?

Câu trả lời ngắn gọn (ý kiến ​​của tôi): chỉ khi triển khai của bạn sử dụng "môi trường thực thi đích tự do".

Tất cả các trích dẫn sau từ C11

5. Môi trường

Một triển khai dịch các tệp nguồn C và thực thi các chương trình C trong hai môi trường hệ thống xử lý dữ liệu, môi trường này sẽ được gọi là môi trường dịch và môi trường thực thi […]

5.1.2 Môi trường thực thi

Hai môi trường thực thi được xác định: tự do và được lưu trữ. Trong cả hai trường hợp, khởi động chương trình xảy ra khi một hàm C được chỉ định được gọi bởi môi trường thực thi.

5.1.2.1 Môi trường hạ cánh

Trong môi trường tự do (trong đó việc thực thi chương trình C có thể diễn ra mà không có bất kỳ lợi ích nào của hệ điều hành), tên và kiểu của hàm được gọi khi khởi động chương trình được xác định bằng cách triển khai.

5.1.2.2 Môi trường được lưu trữ

Môi trường lưu trữ không cần được cung cấp, nhưng phải phù hợp với các thông số kỹ thuật sau nếu có.

5.1.2.2.1 Khởi động chương trình

Hàm được gọi khi khởi động chương trình có tên là main . [...] Nó sẽ được định nghĩa với kiểu trả về là int và không có tham số [...] hoặc với hai tham số [...] hoặc tương đương hoặc theo một số cách thực thi khác được xác định.

Từ những điều này, những điều sau đây được quan sát thấy:

  • Chương trình C11 có thể có môi trường thực thi tự do hoặc được lưu trữ và hợp lệ.
  • Nếu nó có một đích tự do, thì không cần phải tồn tại một hàm chính.
  • Nếu không, phải có một giá trị trả về kiểu int .

Trong môi trường thực thi tự do, tôi sẽ tranh luận rằng đó là một chương trình hợp lệ không cho phép khởi động xảy ra, bởi vì không có chức năng nào cho điều đó theo yêu cầu trong 5.1.2. Trong môi trường thực thi được lưu trữ, mặc dù mã của bạn giới thiệu một đối tượng có tên là main , nó không thể cung cấp giá trị trả về, vì vậy tôi sẽ tranh luận rằng nó không phải là một chương trình hợp lệ theo nghĩa này, mặc dù người ta cũng có thể tranh luận như vậy trước đó nếu chương trình không nghĩa là được thực thi (ví dụ trên có thể chỉ muốn cung cấp dữ liệu), sau đó nó không cho phép thực hiện điều đó.

Là 'int main;' một chương trình C ++ hợp lệ?

Câu trả lời ngắn gọn (ý kiến ​​của tôi): chỉ khi triển khai của bạn sử dụng "môi trường thực thi đích tự do".

Trích dẫn từ C ++ 14

3.6.1 Chức năng chính

Một chương trình phải chứa một hàm toàn cục được gọi là main, là hàm khởi động được chỉ định của chương trình. Việc triển khai được xác định liệu một chương trình trong môi trường đích tự do có được yêu cầu để xác định một chức năng chính hay không. [...] Nó sẽ có kiểu trả về là kiểu int, nhưng nếu không thì kiểu của nó là kiểu thực thi. [...] Tên chính không được bảo lưu.

Ở đây, trái ngược với tiêu chuẩn C11, ít hạn chế hơn áp dụng cho môi trường thực thi đích tự do, vì không có chức năng khởi động nào được đề cập, trong khi đối với môi trường thực thi được lưu trữ, trường hợp này khá giống với C11.

Một lần nữa, tôi sẽ tranh luận rằng đối với trường hợp được lưu trữ, mã của bạn không phải là chương trình C ++ 14 hợp lệ, nhưng tôi chắc chắn rằng nó dành cho trường hợp đích.

Vì câu trả lời của tôi chỉ xem xét môi trường thực thi , nên tôi nghĩ câu trả lời của dasblinkenlicht sẽ có tác dụng, vì việc nhầm lẫn tên xảy ra trong môi trường dịch thuật đã xảy ra trước đó. Ở đây, tôi không chắc rằng các trích dẫn ở trên được tuân thủ nghiêm ngặt như vậy.


4

Tôi cho rằng quan điểm của tôi là tôi thực sự nghĩ rằng đây phải là một lỗi trong môi trường được lưu trữ, phải không?

Lỗi là của bạn. Bạn đã không chỉ định một hàm có tên maintrả về một intvà cố gắng sử dụng chương trình của bạn trong môi trường được lưu trữ.

Giả sử bạn có một đơn vị biên dịch xác định một biến toàn cục có tên main. Điều này cũng có thể hợp pháp trong môi trường có yêu cầu tự do bởi vì những gì cấu thành một chương trình còn tùy thuộc vào việc triển khai trong môi trường đích tự do.

Giả sử bạn có một đơn vị biên dịch khác định nghĩa một hàm toàn cục có tên maintrả về một intvà không nhận đối số. Đây chính xác là những gì một chương trình trong môi trường lưu trữ cần.

Mọi thứ đều tốt nếu bạn chỉ sử dụng đơn vị biên dịch đầu tiên trong môi trường tự do và chỉ sử dụng đơn vị thứ hai trong môi trường được lưu trữ. Điều gì sẽ xảy ra nếu bạn sử dụng cả hai trong một chương trình? Trong C ++, bạn đã vi phạm một quy tắc định nghĩa. Đó là hành vi không xác định. Trong C, bạn đã vi phạm quy tắc quy định rằng tất cả các tham chiếu đến một ký hiệu phải nhất quán; nếu chúng không phải là hành vi không xác định. Hành vi không xác định là "ra khỏi tù, tự do!" thẻ cho các nhà phát triển triển khai. Bất cứ điều gì một triển khai thực hiện để đáp ứng với hành vi không xác định đều tuân thủ tiêu chuẩn. Việc triển khai không phải cảnh báo về, chứ đừng nói đến việc phát hiện, hành vi không xác định.

Điều gì sẽ xảy ra nếu bạn chỉ sử dụng một trong những đơn vị biên dịch đó, nhưng lại sử dụng sai (đó là những gì bạn đã làm)? Ở C, tình hình đã rõ ràng. Không xác định được hàm mainở một trong hai dạng chuẩn trong môi trường được lưu trữ là hành vi không xác định. Giả sử bạn không xác định maingì cả. Trình biên dịch / trình liên kết không nói gì về lỗi này. Việc họ phàn nàn là một điều tốt đẹp thay cho họ. Việc chương trình C được biên dịch và liên kết mà không có lỗi là lỗi của bạn, không phải của trình biên dịch.

Nó kém rõ ràng hơn một chút trong C ++ vì không xác định được hàm maintrong môi trường được lưu trữ là một lỗi chứ không phải là hành vi không xác định (nói cách khác, nó phải được chẩn đoán). Tuy nhiên, một quy tắc định nghĩa trong C ++ có nghĩa là các trình liên kết có thể khá ngu ngốc. Công việc của trình liên kết là giải quyết các tham chiếu bên ngoài và nhờ một quy tắc định nghĩa, trình liên kết không cần phải biết những ký hiệu đó có nghĩa là gì. Bạn đã cung cấp một ký hiệu được đặt tên main, trình liên kết đang mong đợi thấy một ký hiệu có tên main, vì vậy tất cả đều tốt nếu trình liên kết có liên quan.


4

Đối với C cho đến nay nó là hành vi được xác định thực hiện.

Như ISO / IEC9899 nói:

5.1.2.2.1 Khởi động chương trình

1 Hàm được gọi khi khởi động chương trình có tên là main. Việc thực hiện tuyên bố không có nguyên mẫu nào cho chức năng này. Nó sẽ được định nghĩa với kiểu trả về là int và không có tham số:

int main(void) { /* ... */ }

hoặc với hai tham số (ở đây gọi là argc và argv, mặc dù bất kỳ tên nào cũng có thể được sử dụng, vì chúng là cục bộ của hàm mà chúng được khai báo):

int main(int argc, char *argv[]) { /* ... */ }

hoặc tương đương; hoặc theo một số cách thức triển khai khác được xác định.


3

Không, đây không phải là một chương trình hợp lệ.

Đối với C ++, điều này gần đây đã được tạo ra một cách rõ ràng bởi báo cáo lỗi 1886: Liên kết ngôn ngữ cho main () cho biết:

Dường như không có bất kỳ hạn chế nào đối với việc cung cấp cho main () một liên kết ngôn ngữ rõ ràng, nhưng nó có lẽ phải được hỗ trợ sai hoặc có điều kiện.

và một phần của giải pháp bao gồm thay đổi sau:

Một chương trình khai báo một biến chính ở phạm vi toàn cục hoặc khai báo tên chính với liên kết ngôn ngữ C (trong bất kỳ không gian tên nào) là không đúng.

Chúng ta có thể tìm thấy từ ngữ này trong tiêu chuẩn nháp C ++ mới nhất N4527 , là bản nháp C ++ 1z.

Các phiên bản mới nhất của cả clang và gcc hiện đã mắc lỗi này ( xem trực tiếp ):

error: main cannot be declared as global variable
int main;
^

Trước báo cáo lỗi này, đó là hành vi không xác định mà không cần chẩn đoán. Mặt khác, mã không hợp lệ yêu cầu chẩn đoán, trình biên dịch có thể biến điều này thành cảnh báo hoặc lỗi.


Cảm ơn các cập nhật! Thật tuyệt khi thấy điều này hiện đang được áp dụng với chẩn đoán trình biên dịch. Tuy nhiên, tôi phải nói rằng tôi tìm thấy những thay đổi trong cách ghép kênh tiêu chuẩn C ++. (Để biết thông tin cơ bản, hãy xem các nhận xét ở trên liên quan đến tên mangling of main().) Tôi hiểu lý do của việc không cho phép main()có một đặc tả liên kết rõ ràng, nhưng tôi không hiểu nó bắt buộc main()phải có liên kết C ++ . Tất nhiên, tiêu chuẩn không đề cập trực tiếp đến cách xử lý mối liên kết ABI / ghép tên, nhưng trong thực tế (ví dụ, với Itanium ABI), điều này sẽ được giải main()quyết _Z4mainv. Tôi đang thiếu gì?
Geoff Nixon

Tôi nghĩ rằng bình luận của supercat bao gồm điều đó. Nếu việc triển khai đang thực hiện công việc của riêng nó trước khi gọi người dùng xác định chính thì nó có thể dễ dàng chọn gọi một tên bị xáo trộn thay thế.
Shafik Yaghmour
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.