P
pete
pete said:The answer to the question, is "No".
[#8] No other conversions are performed implicitly;
After rethinking the "implicitly" qualifier,
I think The answer might be "it depends".
pete said:The answer to the question, is "No".
[#8] No other conversions are performed implicitly;
Don't go soft on us pete. You were right the first time (I think). Thepete said:pete said:CBFalconer said:Barry Schwarz wrote:Are you saying that calling a von-variadic function with a proper
prototype in scope will still have char, short, and float
promoted?
As usual, it depends.
The answer to the question, is "No".
[#8] No other conversions are performed implicitly;
After rethinking the "implicitly" qualifier,
I think The answer might be "it depends".
Dan Pop said:In <[email protected]> Leor Zolman
In your opinion, how many of them had to pay it from their own pocket? ;-)
Leor Zolman said:Actually, it /is/ rather unintuitive to me that in the modern world of the
flat memory model, you can't just pass a foo * in order to print its value
(and be blessed by the Standard) without first casting it to void *.
That's why I wanted to make sure. But if that's the way it is, that's the
way it is. Just one more item for my posting checklist.
Stephen said:The C Standard does not require a flat memory model
and C is implemented on many systems which don't use one.
While the behavior of passing an incorrectly typed pointer
works on flat memory systems,
it can't be blessed by the Standard
while retaining support for non-flat systems.
In said:pete said:The answer to the question, is "No".[#8] No other conversions are performed implicitly;
After rethinking the "implicitly" qualifier,
I think The answer might be "it depends".
In said:pete said:CBFalconer wrote:
Barry Schwarz wrote:
Are you saying that calling a von-variadic function with a proper
prototype in scope will still have char, short, and float
promoted?
As usual, it depends.
The answer to the question, is "No".[#8] No other conversions are performed implicitly;
After rethinking the "implicitly" qualifier,
I think The answer might be "it depends".
You actually have to rethink the as-if rule. The compiler can perform
any conversions it wants, as long as no correct program can tell the
difference.
void display(char c)
{
putchar(c);
}
int main()
{
char c = 'a';
display(c);
...
}
by converting char arguments to int and having the functions defined with
char parameters by expecting them to be passed as int's. If such
functions only use the LSB of their char parameters, no correct program
will be able to tell the difference. And this scenario is quite
popular on implementations passing the arguments in registers.
In said:[email protected] (Dan Pop) said:In said:pete wrote:
CBFalconer wrote:
Barry Schwarz wrote:
Are you saying that calling a von-variadic function with a proper
prototype in scope will still have char, short, and float
promoted?
As usual, it depends.
The answer to the question, is "No".
[#8] No other conversions are performed implicitly;
After rethinking the "implicitly" qualifier,
I think The answer might be "it depends".
You actually have to rethink the as-if rule. The compiler can perform
any conversions it wants, as long as no correct program can tell the
difference.
void display(char c)
{
putchar(c);
}
int main()
{
char c = 'a';
display(c);
...
}
by converting char arguments to int and having the functions defined with
char parameters by expecting them to be passed as int's. If such
functions only use the LSB of their char parameters, no correct program
will be able to tell the difference. And this scenario is quite
popular on implementations passing the arguments in registers.
Hmm. I wouldn't actually describe that as a "conversion"; rather, I'd
say that the argument-passing convention for type char passes
int-sized chunks of data.
The easy way out for printf would be something like %q which expects a
pointer to a void function taking no arguments. However, given that %p
itself is virtually never used in real world programs, and that
%lx or %llx do work on the pointer converted to the appropriate integer
type, there is little point on adding %q.
In said:[email protected] (Dan Pop) said:The easy way out for printf would be something like %q which expects a
pointer to a void function taking no arguments. However, given that %p
itself is virtually never used in real world programs, and that
%lx or %llx do work on the pointer converted to the appropriate integer
type, there is little point on adding %q.
%p is indispensable[*] on systems without flat address space
(for example, on MS-DOS it prints segmentffset, on 8051 it tells you
which page the pointer points to, and presumably on these "semi-64 bit"
contraptions that are coming out, it will print segmentffset).
Admittedly I've never used it except in recording of debug information.
Windows 3.1 crash messages printed their addresses in the same format,
so I would conjecture that Windows still uses "%p" to print the
address of where programs crashed (virtually every day, in real world PCs)
[*] Of course you can do the (unsigned char *)&ptr thing but that is tedious,
and using %lx is relying on undefined behaviour.
(Old Wolf) said:[email protected] (Dan Pop) said:The easy way out for printf would be something like %q which expects a
pointer to a void function taking no arguments. However, given that %p
itself is virtually never used in real world programs, and that
%lx or %llx do work on the pointer converted to the appropriate integer
type, there is little point on adding %q.
%p is indispensable[*] on systems without flat address space
Have I ever advocating dropping %p from the standard? If not, what
exactly is your point?
You got it wrong: using %p for function pointers *is* relying on undefined
behaviour, using %lx for function pointers converted to unsigned long is
NOT undefined behaviour (such conversions are *explicitly* allowed by the
standard).
Only in C99 <G> whose applicability I thought you still disputed </>,In <[email protected]> (e-mail address removed) (Old Wolf) writes:[*] Of course you can do the (unsigned char *)&ptr thing but that is tedious,
and using %lx is relying on undefined behaviour.
You got it wrong: using %p for function pointers *is* relying on undefined
behaviour, using %lx for function pointers converted to unsigned long is
NOT undefined behaviour (such conversions are *explicitly* allowed by the
standard).
In said:Only in C99 <G> whose applicability I thought you still disputed </>,In <[email protected]> (e-mail address removed) (Old Wolf) writes:[*] Of course you can do the (unsigned char *)&ptr thing but that is tedious,
and using %lx is relying on undefined behaviour.
You got it wrong: using %p for function pointers *is* relying on undefined
behaviour, using %lx for function pointers converted to unsigned long is
NOT undefined behaviour (such conversions are *explicitly* allowed by the
standard).
and it is (still) UB "f the result cannot be represented in the
integer type" 6.3.2.3p6.
For data pointers you can prevent this by
using intptr_t if present, but even then it's not guaranteed to be
*be* long, and there isn't a *printf modifier for it; the unsigned
version (as always) can be safely (no UB) cast but if that narrows the
result might not be useful; and intptr_t isn't guaranteed for
function pointers at all.
^^^^^^^^^^^^^^^There are damn few machines nowadays where casting to either void* or
ulong shouldn't be safe, although perhaps lossy; and for those few it
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.