By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,491 Members | 1,192 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,491 IT Pros & Developers. It's quick & easy.

output from program - why?

P: n/a
I just recently took a C programming test (which was a total farce - but
thats not the point). The code below is a combination of two questions that
were included in the test and I was hoping to raise a few questions about
it. First, the code:

#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)

int increment(int *in)
{
(*in)++;
/* *in++; */ /* Doesnt work*/
return *in;
}

int main(void)
{
int i=1;
printf("%s %s\n", g(f((1,2),3)), h(f((1,2),3)));
printf("%i%i\n", increment(&i), increment(&i));
return 0;
}
The output from the above is:
f((1,2),3) (1,2)3
32

I have 3 questions...

1) Why is the output of the first line so? I have never come across # in
defines.

2) What is the difference between (*in)++ and *in++ ? obviously the latter
doesnt work as I have tested it. Is this because the ++ has higher priority
over *?

3) The output from the last printf is 32, which I suspect because the
variable arguements to printf are executed in reverse order, is this
correct?

Many Thanks
Allan
May 30 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Allan M. Bruce wrote:
I just recently took a C programming test (which was a total farce - but
thats not the point). The code below is a combination of two questions that
were included in the test and I was hoping to raise a few questions about
it. First, the code:

#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)

int increment(int *in)
{
(*in)++;
/* *in++; */ /* Doesnt work*/
return *in;
}

int main(void)
{
int i=1;
printf("%s %s\n", g(f((1,2),3)), h(f((1,2),3)));
printf("%i%i\n", increment(&i), increment(&i));
return 0;
}
The output from the above is:
f((1,2),3) (1,2)3
32
[...skip...]
3) The output from the last printf is 32, which I suspect because the
variable arguements to printf are executed in reverse order, is this
correct?


In my xterm the output is
f((1,2),3) (1,2)3
23
I used the gcc compiler 3.1 to compile your program.
It seems, that the order of executing arguments is
compiler dependent.
May 30 '06 #2

P: n/a
1) for first line ## operator is for concatenating two string so when
you call function f(a,b) it will give u result "ab"
#define g(a) #a
when you call g(xyz) it give you result xyz now i think you can make
the output of first line.

2) (*in)++ increments whatever 'in' points to but *in++ first
increment the pointer i.e. increment the address then access the
content. it is due to associativity of ++ operator which is left to
right.

3)it depnds on compiler to compiler on some compiler it will give 23.
in C there is no fix rule.

May 30 '06 #3

P: n/a
Bart Rider wrote:
Allan M. Bruce wrote:
I just recently took a C programming test (which was a total farce -
but thats not the point). The code below is a combination of two
questions that were included in the test and I was hoping to raise a
few questions about it. First, the code:

#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)

int increment(int *in)
{
(*in)++;
/* *in++; */ /* Doesnt work*/
That is because *in++ is equivalent to *(in++). This should be covered
in the precedence table of whatever text book you are using.
return *in;
}

int main(void)
{
int i=1;
printf("%s %s\n", g(f((1,2),3)), h(f((1,2),3)));
printf("%i%i\n", increment(&i), increment(&i));
return 0;
}
<snip>
3) The output from the last printf is 32, which I suspect because the
variable arguements to printf are executed in reverse order, is this
correct?


In my xterm the output is
f((1,2),3) (1,2)3
23
I used the gcc compiler 3.1 to compile your program.
It seems, that the order of executing arguments is
compiler dependent.


The order of execution is unspecified, which means it can vary not only
from compiler to compiler, but even on consecutive runs of the program.
So you should not write code like that shown.

This is in the comp.lang.c FAQ http://c-faq.com/ specifically question
3.7. The FAQ should be consulted prior to posting.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
May 30 '06 #4

P: n/a
Allan M. Bruce wrote:
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)

int increment(int *in)
{
(*in)++;
/* *in++; */ /* Doesnt work*/
return *in;
}

int main(void)
{
int i=1;
printf("%s %s\n", g(f((1,2),3)), h(f((1,2),3)));
printf("%i%i\n", increment(&i), increment(&i));
return 0;
}
The output from the above is:
f((1,2),3) (1,2)3
32

I have 3 questions...

1) Why is the output of the first line so? I have never come across # in
defines.
If you want to learn C, you should find an appropriate text which covers
the full preprocessor. It is included in the Standard, of course, but
that is harder to read.

The expression h(f((1,2),3)) results in undefined behavior. The results
of the preprocessing concatenation operator is only defined if the
results is a preprocessing token. That is not true in this case.
3) The output from the last printf is 32, which I suspect because the
variable arguements to printf are executed in reverse order, is this
correct?


The second printf statement invokes increment() twice. Increment
modifies the value of i. The Standard does not specify the order in
which arguments are evaluated, so the output order of the two values is
unspecified.

--
Thad
May 30 '06 #5

P: n/a
Bob
On Tue, 30 May 2006 10:37:52 +0100, "Allan M. Bruce"
<al*****@TAKEAWAYdsl.pipex.com> wrote:
The output from the above is:
f((1,2),3) (1,2)3
32

I have 3 questions...

1) Why is the output of the first line so? I have never come across # in
defines.
This one is tricky. Note that the output of the first string in the
printf expression is stripped of the g but not the f. But the second
argument is stripped of both h and f.

The # in a define is a # operator or a "stringization" operator, if
you will. The argument and the preceding # is replaced by a string
whose content is the argument. It stops further macro expansion since
macros are not searched for in strings.

The ## operator allows concatenation of two adjacent 'tokens' into
one.

g is a function-like macro that replaces its argument by a
string-form. So the macro substitution sequence is something like
this (please forgive typos):

printf("%s %s\n", g(f((1,2),3)), h(f((1,2),3)));

printf("%s %s\n", "f((1,2),3)",g(f((1,2),3)));
/* The third argument is now a string. */

printf("%s %s\n", "f((1,2),3)",g((1,2),3));
/* The fourth argument was concatenated by f's expansion. */

printf("%s %s\n", "f((1,2),3)","(1,2),3)";
Prints 'f((1,2),3) (1,2)3'.

2) What is the difference between (*in)++ and *in++ ? obviously the latter
doesnt work as I have tested it. Is this because the ++ has higher priority
over *?
Yes, *in++ increments the pointer 'in' first, then dereferences the
value. It is a precedence issue.

3) The output from the last printf is 32, which I suspect because the
variable arguements to printf are executed in reverse order, is this
correct?


The order of evaluation of arguments in functions is implementation
defined. My implementation actually gives 23.

It is a poorly designed program that depends upon implementation
defined behavior. You get 32 and I get 23 from the same program! It
would drive people crazy, at least me :-) .

Hence, do not depend upon the order of evaluation of function
arguments.

Best wishes,

Bob
May 30 '06 #6

P: n/a

"Bob" <rw****@operaNOSPAMmail.com> wrote in message
news:el********************************@4ax.com...
On Tue, 30 May 2006 10:37:52 +0100, "Allan M. Bruce"
<al*****@TAKEAWAYdsl.pipex.com> wrote:
The output from the above is:
f((1,2),3) (1,2)3
32

I have 3 questions...

1) Why is the output of the first line so? I have never come across # in
defines.


This one is tricky. Note that the output of the first string in the
printf expression is stripped of the g but not the f. But the second
argument is stripped of both h and f.

The # in a define is a # operator or a "stringization" operator, if
you will. The argument and the preceding # is replaced by a string
whose content is the argument. It stops further macro expansion since
macros are not searched for in strings.

The ## operator allows concatenation of two adjacent 'tokens' into
one.

g is a function-like macro that replaces its argument by a
string-form. So the macro substitution sequence is something like
this (please forgive typos):

printf("%s %s\n", g(f((1,2),3)), h(f((1,2),3)));

printf("%s %s\n", "f((1,2),3)",g(f((1,2),3)));
/* The third argument is now a string. */

printf("%s %s\n", "f((1,2),3)",g((1,2),3));
/* The fourth argument was concatenated by f's expansion. */

printf("%s %s\n", "f((1,2),3)","(1,2),3)";
Prints 'f((1,2),3) (1,2)3'.

2) What is the difference between (*in)++ and *in++ ? obviously the latter
doesnt work as I have tested it. Is this because the ++ has higher
priority
over *?


Yes, *in++ increments the pointer 'in' first, then dereferences the
value. It is a precedence issue.

3) The output from the last printf is 32, which I suspect because the
variable arguements to printf are executed in reverse order, is this
correct?


The order of evaluation of arguments in functions is implementation
defined. My implementation actually gives 23.

It is a poorly designed program that depends upon implementation
defined behavior. You get 32 and I get 23 from the same program! It
would drive people crazy, at least me :-) .

Hence, do not depend upon the order of evaluation of function
arguments.

Best wishes,

Bob


Thanks for the helpful response
Allan
May 31 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.