extending printf

B

BartC

Ben Bacarisse said:
I think you proposal is just a little off. You need, in my opinion,
%?d. The compiler can then determine the right length modifier, but
surely you know you want a signed decimal conversion? %?x does hex
conversion for an unsigned type of whatever length. For example, when
the argument is a size_t, %?x would generate %ux. You could, as final
touch, allow %?? which would fill in the length *and* decide on one of
'd', 'u' or 'g' for the conversion specifier based on the type.

Yes, %?? would tick all the boxes (apart from not being able to use just %?
in the majority of cases).

In general, you might have a variable with a typedef-ed type like this:

T a;

where the only thing you know about T is that it's numeric (and might
further know that it's an integer type). And want to quickly print the value
of it:

printf("A = % ....\n", a);

In this case, you don't necessarily know if a is signed or not. You can find
out, but the idea is to avoid going to that effort. And also if T changes,
or this code fragment gets pasted elsewhere where T might be different, then
you want to avoid having to update all these format specifiers.

Actually the same applies even when T isn't a typedef; one day it might just
change from int to long long int; at ordinary warning levels, you will not
be aware anything is amiss.

Of course in the case of the format string not being a constant, then you
can't really use this, unless somehow the compiler can impart type
information to the printf handler, but that would be a bigger, more
disruptive change to how printf works.

(My point of view is from writing this stuff outside of C where you might
just do 'println a'; in general you don't need to specify anything at all,
unless you want extra control over the formatting, but even then you don't
normally need to say what the type of the variable is - the compiler knows
that already, and better than you!)
 
B

Ben Bacarisse

Ben Bacarisse said:
I think you proposal is just a little off. You need, in my opinion,
%?d. The compiler can then determine the right length modifier, but
surely you know you want a signed decimal conversion? %?x does hex
conversion for an unsigned type of whatever length. For example, when
the argument is a size_t, %?x would generate %ux.

%zx of course.
 
K

Keith Thompson

Ben Bacarisse said:
I think you proposal is just a little off. You need, in my opinion,
%?d. The compiler can then determine the right length modifier, but
surely you know you want a signed decimal conversion? %?x does hex
conversion for an unsigned type of whatever length. For example, when
the argument is a size_t, %?x would generate %ux. You could, as final
touch, allow %?? which would fill in the length *and* decide on one of
'd', 'u' or 'g' for the conversion specifier based on the type.

%?? would collide too easily with trigraphs.
 
B

Ben Bacarisse

Keith Thompson said:
%?? would collide too easily with trigraphs.

Good point -- it's a problem just waiting to happen (but then that's
trigraphs for you). The second ? should probably be something like #.
 
S

Seungbeom Kim

Specifiers for user defined types could be added with an appropriate
pragma, something like:

typedef struct
{
int x,y;
} Point;

void printPoint( FILE* fp, const Point* p );

#pragma specifier (Point*,printPoint)

...

Point point = {1,2};

printf( "%?\n", &point );

printf doesn't know the types of the arguments, so the compiler
has to match the types with the corresponding print functions.
(Hence the need for #pragma rather than a library function like
SetNewPrintfFormat.)

However, I doubt if this idea can implemented so that it works in all cases:

#pragma specifier (Point*, printPoint)
#pragma specifier (Shape*, printShape)

void *p;
if (rand() % 2)
p = &point;
else
p = &shape;
printf("%?\n", p);

Now how can the compiler figure out at compile time which function to use?
 
M

Martin Shobe

printf doesn't know the types of the arguments, so the compiler
has to match the types with the corresponding print functions.
(Hence the need for #pragma rather than a library function like
SetNewPrintfFormat.)

However, I doubt if this idea can implemented so that it works in all cases:

#pragma specifier (Point*, printPoint)
#pragma specifier (Shape*, printShape)

void *p;
if (rand() % 2)
p = &point;
else
p = &shape;
printf("%?\n", p);

Now how can the compiler figure out at compile time which function to use?

I would assume that the compiler would use the type of p, i.e. void *.

Martin Shobe
 
S

Stefan Ram

Seungbeom Kim said:
Now how can the compiler figure out at compile time which function to use?

I have invented something! I think I am going to call it
»object-oriented programming«. I am going to write a
preprocessor for C to make this style of programming
easier. I might call the preprocessor »cfront«.

#include <stdio.h> /* printf */

struct o { void( *print )( void const * const); };
void print( void const * const p )
{ struct o const * const o = p; o->print( p ); }

struct a { struct o o; int i; };
void printa( void const * const p )
{ struct a const * const a = p; printf( "%d\n", a->i ); }

struct b { struct o o; char c; };
void printb( void const * const p )
{ struct b const * const b = p; printf( "%c\n", b->c ); }

int main()
{ struct a a_ ={ { printa }, 65 }; struct a * a = &a_;
struct b b_ ={ { printb }, 'A' }; struct b * b = &b_;
print( a );
print( b ); }
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,073
Messages
2,570,539
Members
47,197
Latest member
NDTShavonn

Latest Threads

Top