Lane said:
Thanks for your reply. The books on my shelf are woefully inadequate to
shepherd me through type definitions in C99.
Well, the working draft of the current C standard from ISO's website
combined with the second edition of The C Programming Language should
be enough for all predefined types.
I'd like to write a program that creates a variable of every type I'm likely
to meet in C99, and prints it out. So when I want to know the the
conversion argument for a pointer to an unsigned char, I can re-use the
source.
Strictly speaking, you're likely to meet more types than you can
possibly print out. Though the predefined types in C are not numerous,
programs can create any number of composite and derived types.
The printf() and scanf() format specifiers for all the built-in types
are given in the standard, and should be available in any C99 standard
library reference, like the one in dinkumware.com. They're not more
than about fifty and don't take much to learn.
Format specifiers for the types in stdint.h are available in
inttypes.h, (both C99).
#ifdef _WIN32
# define FORMAT_LONG_LONG "I64"
#else
# define FORMAT_LONG_LONG "ll"
#endif
#include <stdio.h>
int main(void)
{
struct foo {
int a;
char b;
signed char c;
unsigned char d;
short e;
unsigned short f;
unsigned int g;
long h;
unsigned long i;
__int64 j;
Non-standard type. Use long long.
Ditto. Use unsigned long long.
}; struct foo foo_obj;
foo_obj.a = 40;
foo_obj.b = 'k';
foo_obj.c = 'k';
foo_obj.d = 'k';
foo_obj.e = 123;
foo_obj.f = 300;
foo_obj.g = 50000;
foo_obj.h = 123123123;
foo_obj.i = 123123123;
foo_obj.j = 123451234512345;
foo_obj.k = 123451234512345;
printf("%i\n", foo_obj.a);
printf("%c\n", foo_obj.b);
printf("%c\n", foo_obj.c);
Use %hhd
printf("%uc\n", foo_obj.d);
Use %hhu
printf("%hi\n", foo_obj.e);
printf("%hc\n", foo_obj.f);
Use %hu
printf("%ui\n", foo_obj.g);
printf("%li\n", foo_obj.h);
printf("%lu\n", foo_obj.i);
printf("%" FORMAT_LONG_LONG "d\n", foo_obj.j );
printf("%" FORMAT_LONG_LONG "d\n", foo_obj.k );
Just use %ll for long long values. Modify with u, d, i, x, X, o as
applicable.
Compiling your code as given above produces:
~$ gcc -Wall -Wextra -std=c99 -pedantic -O4 -o t t.c
t.c: In function 'main':
t.c:20: error: syntax error before '__int64'
t.c:20: warning: no semicolon at end of struct or union
t.c:24: warning: ISO C forbids nested functions
t.c:24: error: syntax error before 'k'
t.c: At top level:
t.c:28: warning: ISO C does not allow extra ';' outside of a function
t.c:30: error: syntax error before '.' token
t.c:43: error: syntax error before string constant
t.c:43: warning: type defaults to 'int' in declaration of 'printf'
t.c:43: error: conflicting types for 'printf'
t.c:43: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:43: warning: data definition has no type or storage class
t.c:44: error: syntax error before string constant
t.c:44: warning: type defaults to 'int' in declaration of 'printf'
t.c:44: error: conflicting types for 'printf'
t.c:44: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:44: warning: data definition has no type or storage class
t.c:45: error: syntax error before string constant
t.c:45: warning: type defaults to 'int' in declaration of 'printf'
t.c:45: error: conflicting types for 'printf'
t.c:45: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:45: warning: data definition has no type or storage class
t.c:46: error: syntax error before string constant
t.c:46: warning: type defaults to 'int' in declaration of 'printf'
t.c:46: error: conflicting types for 'printf'
t.c:46: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:46: warning: data definition has no type or storage class
t.c:47: error: syntax error before string constant
t.c:47: warning: type defaults to 'int' in declaration of 'printf'
t.c:47: error: conflicting types for 'printf'
t.c:47: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:47: warning: data definition has no type or storage class
t.c:48: error: syntax error before string constant
t.c:48: warning: type defaults to 'int' in declaration of 'printf'
t.c:48: error: conflicting types for 'printf'
t.c:48: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:48: warning: data definition has no type or storage class
t.c:51: error: syntax error before string constant
t.c:51: warning: type defaults to 'int' in declaration of 'printf'
t.c:51: error: conflicting types for 'printf'
t.c:51: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:51: warning: data definition has no type or storage class
t.c:52: error: syntax error before string constant
t.c:52: warning: type defaults to 'int' in declaration of 'printf'
t.c:52: error: conflicting types for 'printf'
t.c:52: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:52: warning: data definition has no type or storage class
t.c:53: error: syntax error before string constant
t.c:53: warning: type defaults to 'int' in declaration of 'printf'
t.c:53: error: conflicting types for 'printf'
t.c:53: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:53: warning: data definition has no type or storage class
t.c:54: error: syntax error before string constant
t.c:54: warning: type defaults to 'int' in declaration of 'printf'
t.c:54: error: conflicting types for 'printf'
t.c:54: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:54: warning: data definition has no type or storage class
t.c:55: error: syntax error before string constant
t.c:55: warning: type defaults to 'int' in declaration of 'printf'
t.c:55: error: conflicting types for 'printf'
t.c:55: note: a parameter list with an ellipsis can't match an empty
parameter name list declaration
t.c:55: warning: data definition has no type or storage class
Q3) How would I extend foo to have the conversion characters associated
with their type? If I had a field of ten characters, I could capture
expressions like '"%lu"'. This wouldn't help me with print statements like
that for type of size_t:
printf("%lu", (unsigned long)sizeof(thetype));
, but one problem at a time.
Just define macros as inttypes.h does. Most people can type from
memory, but whatever floats your boat.
PS. For size_t C99 defines the %z format specifier.