cprogram-entry-pointportability

Should Portable Types Be Used in the Declaration of a Main Function? (C11)


This question came to me last night, and I couldn't find a definitive answer in my brief surf of Google. Should (or could) I use portable types (i.e int32_t) in the declaration of my program's main function? Example:

// Normal main function, works perfectly fine.
int main(int argc, char* argv[]) {
    return 0;
}

// Portable(?) main function.
#include <stdint.h>
int32_t main(int32_t argc, char* argv[]) {
    return 0;
}

The portable main function compiles (GCC 14.1.1), but is it good practice?


Solution

  • The definition you provide is non-standard. Or better, it is defined by the standard to be "implementation defined" and therefore only allowed if your compiler (implementing the standard) allows such definition.

    I am not aware of major compilers allowing an int32_t return value for main(). However, it must be noted that on various platforms int32_t is just a typedef for int. The standard does allow "equivalent" main() declarations where int is replaced by a type that is indirectly typedef'd from int, however this definitely varies depending on the platform.

    Overall, this is not a portable definition. It may be allowed by the standard but there almost certainly are platforms where this is non-standard conforming. I would avoid it.


    References from C99 standard N1256:

    5.1.2.2.1 Program startup

    1. The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

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

      or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

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

      or equivalent;9) or in some other implementation-defined manner.

    [...]

    9) Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.