2009-10-25 12 views
24

La norma establece explícitamente que main tiene dos firmas válidas (es decir, garantizadas para trabajar); a saber:¿Pueden los argumentos de la firma main en C++ tener los calificadores unsiged y const?

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

Mi pregunta es simple, algo como el siguiente sería legal?

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

Mis pruebas dicen 'sí', pero estoy seguro de la respuesta, porque no estoy sobrecargando main cambiando int a unsigned int así como el nivel superior no const -ness de argv? Si lo estoy, entonces eso está claramente prohibido.

Entonces, ¿estas modificaciones están garantizadas para funcionar en un compilador que cumpla con los estándares?

+7

¿por qué le gustaría hacer algo como eso? Simplemente escriba el código de conformidad con el estándar – Glen

+10

Glen, _want_ para escribir el código conforme. Es por eso que hice esta pregunta en primer lugar. – bh9042

+9

Luego declara 'int main (int, char **)' y sigue tu camino. –

Respuesta

33

El estándar de C++ 98 dice en la sección 3.6.1 párrafo 2

Una implementación no predefinir la función principal. Esta función no debe estar sobrecargada. Tendrá un tipo de devolución del tipo int, pero de lo contrario su tipo está definido por la implementación. Todas las implementaciones permitirán tanto las siguientes definiciones de main: int main() y int main(int argc, char* argv[])

Así que no es un mandato de la norma de que el env aceptar main es aceptable, pero es permisible.


Debido a esto se le llama a menudo, aquí es el párrafo anterior exime entornos Autosoportados de nada, pero la documentación de su comportamiento:

Un programa debe contener una función global llamada principal, que es el inicio designada Del programa. Es implementación definida si se requiere un programa en un entorno independiente para definir una función principal .[Nota: en un entorno independiente, el inicio y la terminación están definidos por la implementación; startup contiene la ejecución de constructores para objetos de ámbito de espacio de nombres con duración de almacenamiento estático; La terminación contiene la ejecución de destructores para objetos con duración de almacenamiento estático. ]

+0

Ah, me perdí la parte "tipo" cuando lo leí. – bh9042

1

Por lo que puedo ver al leer el estándar, no cumple con los estándares. Pero no puedo imaginarme un compilador que no te permita hacer esto. Al igual que en el caso, se necesitaría más trabajo del compilador para prohibir específicamente un caso extremo que en su mayoría es inofensivo y muy oscuro.

+0

Amen. su código PUEDE tener problemas para compilar en un compilador hipotético que siga 100% el estándar. Pero la mayoría de los compiladores no, y este caso extremo es probablemente uno de los que permiten lo que técnicamente es un comportamiento ilegal. – DVK

2

Los punteros argv no deben ser const char* const porque el programa puede cambiar los almacenamientos intermedios.

+0

** Solo ** las cadenas, no los punteros a las cuerdas. –

+3

Ese es el punto. ¡No quiero cambiar nada! – bh9042

+2

Entonces no cambie nada. –

0

Puede ser ilegal según el estándar, pero a la mayoría de los motores de ejecución en realidad no les importa. Simplemente presionarán un número entero para argc y un puntero para argv, llame a su main, y espero que los analice correctamente. Por lo tanto, en su ámbito, "garantizado para trabajar" es discutible, ya que al cargador realmente no le importa cómo haya declarado los argumentos.

Si se genera, se llamará a main. Cómo analizas los argumentos depende de ti. Debo aclarar que esto es altamente específico de la plataforma, como casi toda esta pregunta.

Dicho esto, ¿por qué?

+1

1. argc está garantizado para ser no negativo, quiero ver un unsigned en algún lugar allí ...;) 2. Quiero la red de seguridad adicional que ofrece const contra errores estúpidos. Al igual que respondí a jeffaphone, aunque puedo cambiar argv, no quiero o no necesito hacerlo. – bh9042

+1

'main' anterior a C++, e incluso el tiempo de' unsigned'. Independientemente de lo que quieras, 'main' ha sido declarado de esta manera durante mucho, mucho tiempo. ¿Realmente necesitas el compilador para protegerte de modificar 'argv'? Si no tienes ese 'const' ¿accidentalmente vas a reemplazar todo '-' por '/' en tus cadenas' argv'? No me estás vendiendo sobre por qué es necesario. –

+1

Creo que es un punto válido que permitir a los programadores especificar suposiciones y restricciones a través de modificadores como 'unsigned' y' const' debería permitirse en cualquier parte. Si es bueno para las funciones definidas por el usuario, no veo por qué no sería bueno para 'main()' también. –

19

Debe utilizar una de las firmas estándar para cumplir con los estándares.

Entiendo completamente por qué quieres hacerlo a tu manera. La mejor manera es escribir su propia función myMain() o lo que sea con la firma que desee y llamarla desde main(), incluidos los moldes necesarios.

+5

+1 por proporcionar una respuesta útil en lugar de "no entiendo por qué harías esto". –

1

Esto puede no funcionar si el compilador utiliza el nombre de manipulación para main. Es una función de C++ después de todo. Por lo tanto, el enlazador buscará dos "manglings" particulares. Su definición tendría otro nombre destrozado.

Tenga en cuenta que main es especial (no se sobrecarga, no se puede llamar) y es posible que no requiera ningún cambio de nombre.

0

ISO/IEC 9899: TC3

Sección 5.1.2.2.1 inicio del programa

La función llamada al inicio del programa se denomina principal. La implementación no declara el prototipo para esta función. Que se define con un tipo de retorno de int y sin parámetros:

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

o con dos parámetros (denominados aquí como argc y argv, aunque los nombres pueden ser utilizado, ya que son locales al función en la cual están declarados):

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

o equivalente; 9) o de alguna otra manera definida por la implementación.

Cuestiones relacionadas