2009-10-25 7 views
24

Standard wyraźnie stwierdza, że ​​main ma dwa prawidłowe (tj. Gwarantowane do pracy) podpisy; a mianowicie:Czy argumenty podpisu głównego w C++ mogą mieć kwalifikatory nieważone i const?

int main(); 
int main(int, char*[]); 

Moje pytanie jest proste, czy coś takiego będzie legalne?

int main(const unsigned int, const char* const* argv); 

moich testów powiedzieć „tak”, ale jestem pewny odpowiedzi, bo ja nie przeciążania main zmieniając int do unsigned int jak również nieprzestrzegania najwyższym poziomie const -ness od argv? Jeśli tak, to jest to wyraźnie zabronione.

Czy te modyfikacje gwarantują działanie na zgodnym ze standardem kompilatorze?

+7

dlaczego chcesz coś takiego zrobić? Wystarczy napisać zgodny ze standardem kod – Glen

+10

Glen, chciałbym napisać zgodny kod. Właśnie dlatego zadałem to pytanie w pierwszej kolejności. – bh9042

+9

Następnie należy zadeklarować 'int main (int, char **)' i być na dobrej drodze. –

Odpowiedz

33

standard C++ 98 mówi w sekcji 3.6.1 pkt 2

Implementacja nie ma predefine główną funkcję. Ta funkcja nie może być przeciążona. Ma on typ zwrotu typu: int, ale poza tym jego typ jest definiowany przez implementację. Wszystkie implementacje zezwalają oba następujące definicje main: int main() i int main(int argc, char* argv[])

Więc to nie jest upoważniona przez normę ENV że akceptując main jest do zaakceptowania, ale to jest dopuszczalne.


Ponieważ ten określany jest często, oto poprzedni akapit zwolnienia wolnostojące środowisk od wszystkiego ale dokumentowania ich zachowanie:

Program powinien zawierać globalną funkcję o nazwie główny, który jest wyznaczony początek programu. Jest implementacja zdefiniowana , czy program w wolnostojącym środowisku jest wymagany do zdefiniowania głównej funkcji .[Uwaga: w środowisku wolnostojącym uruchomienie i zakończenie to zdefiniowanie implementacji; uruchamianie zawiera wykonanie konstruktorów obiektów zakresu przestrzeni nazw o statycznym czasie przechowywania; terminacja zawiera wykonanie destruktorów dla obiektów o statycznym czasie przechowywania. ]

+0

Ah, tęsknię za częścią "typu", kiedy ją czytam. – bh9042

1

O ile widzę, po przeczytaniu standardu, nie spełniasz standardów. Ale nie mogę sobie wyobrazić kompilatora, który nie pozwoliłby ci tego zrobić. W tym przypadku kompilator będzie potrzebował więcej pracy, aby zablokować przypadek skrajny, który jest w większości nieszkodliwy i mało znany.

+0

Amen. Twój kod MOŻE mieć problemy z kompilacją na hipotetycznym kompilatorze, który w 100% odpowiada standardowi. Jednak większość kompilatorów tego nie robi, a ten skrajny przypadek jest prawdopodobnie jednym z tych, w których pozwalają na to, co jest technicznie nielegalnym zachowaniem. – DVK

2

Poszczególne wskaźniki nie powinny być const char* const, ponieważ program może zmieniać bufory.

+0

** Tylko ** ciągi, a nie wskaźniki do ciągów. –

+3

Właśnie o to chodzi. Nie chcę niczego zmieniać! – bh9042

+2

Nie zmieniaj niczego. –

0

Standard może być niezgodny z prawem, ale w większości przypadków nie ma to znaczenia. Po prostu wypchną liczbę całkowitą dla argc i wskaźnik dla argv, zadzwoń pod numer main i miej nadzieję, że je poprawnie przeanalizujesz. Tak więc, w twoim zasięgu, "gwarantowane działanie" jest dyskusyjne, ponieważ program ładujący naprawdę nie dba o to, co zadeklarowałeś jako argumenty.

Jeśli zostanie utworzony, zostanie wywołany main. Sposób, w jaki analizujesz argumenty, należy do ciebie. Powinienem wyjaśnić, że jest to wysoce zależne od platformy, podobnie jak prawie to całe pytanie.

To powiedziawszy, dlaczego?

+1

1. argc ma gwarantowaną wartość nieujemną, chcę zobaczyć gdzieś tam niepodpisaną ...;) 2. Chcę dodatkowej siatki bezpieczeństwa, która zapewnia przed głupimi błędami. Jakbym zareagował na jeffamaphone, chociaż mogę zmienić Argv, nie chcę ani nie potrzebuję. – bh9042

+1

'main' poprzedza C++, a nawet czas' unsigned'. Niezależnie od tego, co chcesz, "główny" został tak zadeklarowany przez długi, długi czas. Naprawdę potrzebujesz kompilatora, aby ochronić cię przed modyfikacją 'argv'? Jeśli nie masz tego "const", to przypadkiem zamienisz wszystkie znaki "-" na "/" w łańcuchach 'argv'? Nie sprzedajesz mi, dlaczego tak jest. –

+1

Myślę, że jest to ważny punkt, w którym programiści mogą określać założenia i ograniczenia za pomocą modyfikatorów takich jak 'unsigned' i' const', które powinny być dozwolone w dowolnym miejscu. Jeśli jest to dobre dla funkcji zdefiniowanych przez użytkownika, nie widzę powodu, dla którego nie byłoby to dobre dla 'main()'. –

19

Musisz użyć jednej ze standardowych sygnatur zgodnych ze standardem.

W pełni rozumiem, dlaczego chcesz zrobić to po swojemu. Najlepszym sposobem jest napisanie własnej funkcji myMain() lub cokolwiek z podpisem, który chcesz i wywołanie go z głównej(), w tym wymaganych rzutów.

+5

+1 za udzielenie użytecznej odpowiedzi zamiast w przypadku wszystkich innych "Nie rozumiem, dlaczego to zrobiłeś". –

1

Może to nie działać, jeśli kompilator używa funkcji mieszania nazw dla main. W końcu jest to funkcja C++. W związku z tym linker będzie szukał dwóch konkretnych "manglingów". Twoja definicja miałaby inną zniekształconą nazwę.

Należy pamiętać, że main jest specjalny (nie przeciąża, nie można wywołać) i może w ogóle nie wymagać wymieszania nazw.

0

ISO/IEC 9899: TC3

sekcja 5.1.2.2.1 starcie programu

Funkcja nazywa się przy starcie programu o nazwie main. Implementacja nie deklaruje prototypu tej funkcji. Jest określana z typem zwracanej int i bez parametrach:

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

lub z dwoma parametrami (określonych tu jako argc i argv, choć wszelkie nazwy mogą być stosowane, ponieważ są one lokalne dla funkcja, w której są zadeklarowane):

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

lub równoważny, 9) lub w inny sposób określony przez implementację.

Powiązane problemy