NeutronStar
NeutronStar

Reputation: 2157

What are the proper specifiers for limits.h *_MAX constants in C?

I am trying to write a simple C code that shows the maximum values and sizes of various variable types in C. However, I am getting some strange output, such as the sizeof() operator returning -1 for some of the variable types. I think the problem lies in the specifiers I am using in the printf command, since when I change '%e' in my code below to '%d' I get very different output even for those specifiers I didn't change. My question is how to get the proper output I am looking for, i.e., the maximum value for the variable type in the first column and the size of the variable type in the second column.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

int main()
{  

  printf("Float max:   %e    Nbytes:  %d\n",FLT_MAX,sizeof(float));
  printf("Double max:  %e    Nbytes:  %d\n",DBL_MAX,sizeof(double));
  printf("Int max:     %e    Nbytes:  %d\n",INT_MAX,sizeof(int));
  printf("UnInt max:   %e    Nbytes:  %d\n",UINT_MAX,sizeof(unsigned int));
  printf("LongIntmax:  %e    Nbytes:  %d\n",LONG_MAX,sizeof(long));
  printf("UnLong max:  %e    Nbytes:  %d\n",ULONG_MAX,sizeof(unsigned long));
  printf("Longlongmax: %e    Nbytes:  %d\n",LLONG_MAX,sizeof(long long));


  exit(0);
}

The output I get from the code as written is as follows:

Float max:   3.402823e+38    Nbytes:  4       
Double max:  1.797693e+308    Nbytes:  8    
Int max:     1.797693e+308    Nbytes:  2147483647    
UnInt max:   1.797693e+308    Nbytes:  -1    
LongIntmax:  1.797693e+308    Nbytes:  -1    
UnLong max:  1.797693e+308    Nbytes:  -1    
Longlongmax: 1.797693e+308    Nbytes:  -1    

However, if I switch all the '%e' to '%d' and run the code again I get:

Float max:   4    Nbytes:  -1290994504    
Double max:  8    Nbytes:  605613584    
Int max:     2147483647    Nbytes:  4    
UnInt max:   -1    Nbytes:  4    
LongIntmax:  -1    Nbytes:  8    
UnLong max:  -1    Nbytes:  8    
Longlongmax: -1    Nbytes:  8    

The second column output of the first run becomes the first column output of the second run. I am not sure what is going on here. Again, I think I am tying the wrong specifier to the *_MAX constants, but I am not sure if there is another problem I am missing.

Upvotes: 2

Views: 574

Answers (1)

zch
zch

Reputation: 15278

Yes, the problem is with specifiers - you need to have them matching arguments %f/%e/%g for double (and float which gets promoted), %d for signed, %u for unsigned. And l in the middle for each long. Finally size_t needs %zu.

  printf("Float max:   %f    Nbytes:  %zu\n",FLT_MAX,sizeof(float));
  printf("Double max:  %f    Nbytes:  %zu\n",DBL_MAX,sizeof(double));
  printf("Int max:     %d    Nbytes:  %zu\n",INT_MAX,sizeof(int));
  printf("UnInt max:   %u    Nbytes:  %zu\n",UINT_MAX,sizeof(unsigned int));
  printf("LongIntmax:  %ld    Nbytes:  %zu\n",LONG_MAX,sizeof(long));
  printf("UnLong max:  %lu    Nbytes:  %zu\n",ULONG_MAX,sizeof(unsigned long));
  printf("Longlongmax: %lld    Nbytes:  %zu\n",LLONG_MAX,sizeof(long long));

You get -1 because you trigger undefined behavior when format string doesn't match arguments.

Upvotes: 3

Related Questions