strange call

K

Kavya

#include <stdio.h>

main()
{
int *f(void);

f()[2] = 'x'; /* ------(1) */
printf("%c %c %c %c\n", f()[0],
f()[1], f()[2], f()[3]);
}

int *f(void)
{
static int a[] = {'a', 'b', 'c', 'd'};

return &a[0];
}

Output
a b x d


What is happening in 1st line. I am not able to understand.
 
R

Richard Heathfield

Kavya said:
#include <stdio.h>

main()
{
int *f(void);

f()[2] = 'x'; /* ------(1) */
printf("%c %c %c %c\n", f()[0],
f()[1], f()[2], f()[3]);
}

int *f(void)
{
static int a[] = {'a', 'b', 'c', 'd'};

return &a[0];
}

Output
a b x d


What is happening in 1st line. I am not able to understand.

It's a perfectly legal shorthand for:

int *p = f();
p[2] = 'x';

without going to all the trouble and inconvenience of defining a temporary
object p to store the pointer value returned by f.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
 
S

santosh

Kavya said:
#include <stdio.h>

main()
{
int *f(void);

f()[2] = 'x'; /* ------(1) */
printf("%c %c %c %c\n", f()[0],
f()[1], f()[2], f()[3]);
}

int *f(void)
{
static int a[] = {'a', 'b', 'c', 'd'};

return &a[0];
}

Output
a b x d


What is happening in 1st line. I am not able to understand.

In C, a function that returns a value can be a part of a larger
expression. Here a call to f() returns a value of type pointer to int.
The array indexing operator is used on this value to increment it by 2
* sizeof(*f()), in order to modify the third element of f()'s static
array and display it with printf() by the same manner described above.
 
K

Kavya

Richard said:
Kavya said:
#include <stdio.h>

main()
{
int *f(void);

f()[2] = 'x'; /* ------(1) */
printf("%c %c %c %c\n", f()[0],
f()[1], f()[2], f()[3]);
}

int *f(void)
{
static int a[] = {'a', 'b', 'c', 'd'};

return &a[0];
}

Output
a b x d


What is happening in 1st line. I am not able to understand.

It's a perfectly legal shorthand for:

int *p = f();
p[2] = 'x';

without going to all the trouble and inconvenience of defining a temporary
object p to store the pointer value returned by f.
Is it supposed to work fine on Bound Checked Implementation?
 
S

santosh

Kavya said:
Richard said:
Kavya said:
#include <stdio.h>

main()
{
int *f(void);

f()[2] = 'x'; /* ------(1) */
printf("%c %c %c %c\n", f()[0],
f()[1], f()[2], f()[3]);
}

int *f(void)
{
static int a[] = {'a', 'b', 'c', 'd'};

return &a[0];
}

Output
a b x d


What is happening in 1st line. I am not able to understand.

It's a perfectly legal shorthand for:

int *p = f();
p[2] = 'x';

without going to all the trouble and inconvenience of defining a temporary
object p to store the pointer value returned by f.
Is it supposed to work fine on Bound Checked Implementation?

I can't see any reason why it should not.
 
M

Malcolm

Richard Heathfield said:
Kavya said:
#include <stdio.h>

main()
{
int *f(void);

f()[2] = 'x'; /* ------(1) */
printf("%c %c %c %c\n", f()[0],
f()[1], f()[2], f()[3]);
}

int *f(void)
{
static int a[] = {'a', 'b', 'c', 'd'};

return &a[0];
}

Output
a b x d


What is happening in 1st line. I am not able to understand.

It's a perfectly legal shorthand for:

int *p = f();
p[2] = 'x';

without going to all the trouble and inconvenience of defining a temporary
object p to store the pointer value returned by f.
At the cost of considerable trouble and inconvenience for Kavya, who has the
unhappy task of reading this code.
 
F

Frederick Gotham

Kavya:
#include <stdio.h>

main()


Implicit int is a bad thing.

int main(void)
{

{
int *f(void);

f()[2] = 'x'; /* ------(1) */


Array subscripting works as follows in C.

arr

is interpreted as:

*(arr + i)

"arr" implicitly converts to a pointer to the first element of the array,
then "i" is added to this address, then the whole thing is dereferenced.

So, your line of code is equivalent to:

*(f() + 2) = 'x';

The pointer which is returned from the invocation of "f" has 2 added to it,
then the whole thing is dereferenced yielding an L-value, and then an
assignment is performed upon the L-value.
 
K

Keith Thompson

Frederick Gotham said:
Kavya:
#include <stdio.h>

main()


Implicit int is a bad thing.

int main(void)
{

{
int *f(void);

f()[2] = 'x'; /* ------(1) */


Array subscripting works as follows in C.

arr

is interpreted as:

*(arr + i)

"arr" implicitly converts to a pointer to the first element of the array,
then "i" is added to this address, then the whole thing is dereferenced.


That implicit conversion happens only if arr is an array expression.
So, your line of code is equivalent to:

*(f() + 2) = 'x';

The pointer which is returned from the invocation of "f" has 2 added to it,
then the whole thing is dereferenced yielding an L-value, and then an
assignment is performed upon the L-value.

In this case, the value returned by f() is already a pointer, which is
what the indexing operator expects, so no implicit conversion is
necessary. (For the indexing operation to make sense, the pointer has
to be pointing to the first element of an array in memory, but it
still has to be a pointer not an array.)

We think of "[]" as an *array* indexing operator because the prefix is
most commonly an array name, but that's really just a special case; in
general, the prefix is a pointer. If the prefix is an array name,
it's converted to a pointer before the "[]" operator is applied.

(If you're not quite confused enough, read question 6.11 in the
comp.lang.c FAQ, <http://www.c-faq.com/>. Then read the rest of
section 6 if you want to be *less* cofused.)

(The above is a general "you", not directed at Frederick.)
 
R

Richard Heathfield

Context:
f()[2] = 'x';

Malcolm said:
It's a perfectly legal shorthand for:

int *p = f();
p[2] = 'x';

without going to all the trouble and inconvenience of defining a
temporary object p to store the pointer value returned by f.
At the cost of considerable trouble and inconvenience for Kavya, who has
the unhappy task of reading this code.

Yes. I'm not overly keen on it either, but occasionally I've been guilty of
the equivalent, *strchr(foo, bar) = baz, when I knew for sure that bar
appears in foo. Tsk tsk, as they say...

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
 
F

Frederick Gotham

Keith Thompson:
(The above is a general "you", not directed at Frederick.)


; )

It's funny... I think one can gauge one's progress in becoming proficient at
a programming language by counting how many times per day they enounter
something on comp.lang.X that really opens their eyes.

On comp.lang.c++, it's very rare for me.

On comp.lang.c, it's becoming less and less frequent.
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top