|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
#include<stdio.h>
int main() { int a[3][3][3]; printf("%d %d %d %d",a,*a,**a,&a); } I tried the above code and got the same value for a, *a , **a and &a. Can anyone please tell me the reason behind such a behavior? |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
In article <7315e312-e8ca-4f52-8810-360fb5a46e6c@l32g2000hse.googlegroups.com>,
Nikhil Bokare <nbokare@gmail.com> wrote: >#include<stdio.h> >int main() >{ > int a[3][3][3]; > printf("%d %d %d %d",a,*a,**a,&a); >} >I tried the above code and got the same value for a, *a , **a and &a. >Can anyone please tell me the reason behind such a behavior? You should not be printing out pointers with a %d format. A pointer might (or might not) occupy more storage than an int, so if you use a %d format you might be printing out only part of the address of the pointer. It is not uncommon for pointers to be longer than int; it is more common for pointers to -happen- to be the same size as long, but that is not guaranteed. You can use a %p format to write out a pointer to void (so be sure to cast the pointer to (void *) in the argument list, as pointers to different types may have different sizes.) Also, you have specified that your main returns int and yet you have not returned any value from main(). That will work in C99 but has undefined behaviour in C90. -- "I will speculate that [...] applications [...] could actually see a performance boost for most users by going dual-core [...] because it is running the adware and spyware that [...] are otherwise slowing down the single CPU that user has today" -- Herb Sutter |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare said:
> #include<stdio.h> > > int main() > { > int a[3][3][3]; > printf("%d %d %d %d",a,*a,**a,&a); > } > > I tried the above code and got the same value for a, *a , **a and &a. They can't have the same value, because they don't have the same type. a has type int[3][3][3], *a has type int[3][3], **a has type int[3], and &a has type (int *)[3][3][3]. None of these is type int, so %d is inappropriate as a format specifier (and indeed the behaviour if you do this is undefined). Since printf lacks format specifiers for the above-mentioned types, a conversion is required, and the most obvious way to do this is to cast to void *, which of course discards the type information, so when you correct your program to use casts-to-void* and %p instead of %d, you shouldn't necessarily expect to see different values. > Can anyone please tell me the reason behind such a behavior? Mu. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare <nbokare@gmail.com> writes:
> int main() > { > int a[3][3][3]; > printf("%d %d %d %d",a,*a,**a,&a); You should use %p to print pointers. To be really correct, you should also cast all of these values to void *. > } > > I tried the above code and got the same value for a, *a , **a and &a. > Can anyone please tell me the reason behind such a behavior? All of those expressions point to the same byte. It's just in their types that they have some differences. -- char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[] ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p =b,i=24;for( +=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}} |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare <nbokare@gmail.com> writes:
> #include<stdio.h> > > int main() > { > int a[3][3][3]; > printf("%d %d %d %d",a,*a,**a,&a); > } > > I tried the above code and got the same value for a, *a , **a and &a. > Can anyone please tell me the reason behind such a behavior? You're lucky (or unlucky) that the program worked at all. The "%d" format requires an argument of type int. If you give it anything else, you invoke undefined behavior. You're probably getting meaningful results on your implementation, but there are no guarantees. If you want to print a pointer value, use "%p" and convert the argument to void*. You should also terminate your output with a newline ("\n") and return a value from main(); "return 0;" is usually the right thing. Getting to what you're really asking about, you should read section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>. If you're still confused after that, feel free to come back with more specific questions. -- Keith Thompson (The_Other_Keith) <kst-u@mib.org> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Thanks for pointing out my mistakes.
This is my edited program: #include<stdio.h> int main() { int a[3][3][3]; printf("%p %p %p %p",a,*a,**a,&a); return 0; } Its still printing the same value for all of them. How does it happen?? |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Feb 4, 1:46 pm, Nikhil Bokare <nbok...@gmail.com> wrote:
> Thanks for pointing out my mistakes. > This is my edited program: > > #include<stdio.h> > > int main() > { > int a[3][3][3]; > printf("%p %p %p %p",a,*a,**a,&a); > return 0; > > } > > Its still printing the same value for all of them. How does it happen?? Because all of those expressions evaluate to the same location. The address of an array is the same as the address of the first element of the array. The *types* of each expression are different (int (*)[3] [3], int (*)[3], int *, and int (*)[3][3][3], respectively), but they all refer to the same location. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare said:
> Thanks for pointing out my mistakes. > This is my edited program: > > #include<stdio.h> > > int main() > { > int a[3][3][3]; > printf("%p %p %p %p",a,*a,**a,&a); That line should be: printf("%p %p %p %p",(void *)a,(void *)*a,(void *)**a,(void *)&a); > return 0; > } > > Its still printing the same value for all of them. How does it happen?? They have different types, as I explained before, so they have different values, as I explained before. The casts to void * are required, as I explained before. Because the casts to void * discard type information, the differences between the values are also being discarded. Here's a real world parallel question: "I used a GPS to find out the location of an oxygen atom, a water molecule, and a water spillage on a kitchen table, and the GPS gave the same location for all three. Why?" Obviously, these are three very different things. Equally obviously, there's no particular reason why they shouldn't be in precisely the same place. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Richard Heathfield <rjh@see.sig.invalid> writes:
> Nikhil Bokare said: >> #include<stdio.h> >> >> int main() >> { >> int a[3][3][3]; >> printf("%d %d %d %d",a,*a,**a,&a); >> } >> >> I tried the above code and got the same value for a, *a , **a and &a. > > They can't have the same value, because they don't have the same type. a > has type int[3][3][3], *a has type int[3][3], **a has type int[3], and &a > has type (int *)[3][3][3]. None of these is type int, so %d is > inappropriate as a format specifier (and indeed the behaviour if you do > this is undefined). Since printf lacks format specifiers for the > above-mentioned types, a conversion is required, and the most obvious way > to do this is to cast to void *, which of course discards the type > information, so when you correct your program to use casts-to-void* and %p > instead of %d, you shouldn't necessarily expect to see different values. The object ``a'' has type int[3][3][3], but the expression ``a'', in this context, has type int(*)[3][3], or pointer to array 3 of array 3 of int; that's the type of the argument that's being passed to printf. Similarly, the expression ``*a'' has type int(*)[3], the expression ``**a'' has type int*, and the expression ``&a'' has type int(*p)[3][3][3]. (I *think* I got all those right; someone will certainly correct me if I didn't.) Certainly none of these has type int, so "%d" is the wrong format. Here's my version of the OP's program, adding ***a to the mix: #include<stdio.h> int main(void) { int a[3][3][3] = {0}; int (*b)[3][3] = a; int (*c)[3] = *a; int *d = **a; int e = ***a; int (*f)[3][3][3] = &a; printf("%p %p %p %d %p\n", (void*)b, (void*)c, (void*)d, e, (void*)f); return 0; } -- Keith Thompson (The_Other_Keith) <kst-u@mib.org> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare wrote:
> > Thanks for pointing out my mistakes. > This is my edited program: > > #include<stdio.h> > > int main() > { > int a[3][3][3]; > printf("%p %p %p %p",a,*a,**a,&a); > return 0; > } > > Its still printing the same value for all of them. How does it happen?? Given the definition of "a": int a[3][3][3]; What do the following actually mean: a *a **a &a -- +-------------------------+--------------------+-----------------------+ | Kenneth J. Brody | www.hvcomputer.com | #include | | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> | +-------------------------+--------------------+-----------------------+ Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com> |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare <nbokare@gmail.com> writes:
> Thanks for pointing out my mistakes. > This is my edited program: > > #include<stdio.h> > > int main() > { > int a[3][3][3]; > printf("%p %p %p %p",a,*a,**a,&a); > return 0; > } > > Its still printing the same value for all of them. How does it happen?? Read section 6 of the comp.lang.c FAQ. -- Keith Thompson (The_Other_Keith) <kst-u@mib.org> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare wrote:
> > #include<stdio.h> > > int main() { > int a[3][3][3]; > printf("%d %d %d %d",a,*a,**a,&a); > } > > I tried the above code and got the same value for a, *a , **a and > &a. Can anyone please tell me the reason behind such a behavior? It's accurate. Any response is accurate when behaviour is undefined. Which is the result of lying to printf about the type of data passed to it. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Nikhil Bokare wrote:
> > Thanks for pointing out my mistakes. This is my edited program: > > #include <stdio.h> > > int main() { > int a[3][3][3]; > printf("%p %p %p %p",a,*a,**a,&a); > return 0; > } > > Its still printing the same value for all of them. How does it > happen?? Because you are still lying to printf and getting undefined behaviour. %p requires a void* parameter. I also fixed your #include statement. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
Keith Thompson said:
<snip> > The object ``a'' has type int[3][3][3], but the expression ``a'', in > this context, has type int(*)[3][3], or pointer to array 3 of array 3 > of int; that's the type of the argument that's being passed to printf. Good spot. (Duh@me.) Thanks, Keith. <snip> -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
"Richard Heathfield" <rjh@see.sig.invalid> wrote in message news:G56dnXfk_dBdxjraRVnygwA@bt.com... > Nikhil Bokare said: > >> #include<stdio.h> >> >> int main() >> { >> int a[3][3][3]; >> printf("%d %d %d %d",a,*a,**a,&a); >> } >> I tried the above code and got the same value for a, *a , **a and &a. I can't get my head around these either: >a has type int[3][3][3] Yet you dereference a in your next statement, so a's type must be ref something.: > *a has type int[3][3] >**a has type int[3] And again, so it must have been ref ref something (to use Algol68 notation for a minute). >&a has type (int *)[3][3][3]. Now that one's really got me: &a is a 3D array of ref int? I expected ref [3][3][3]int. An array name decomposes to a ref to the first element. Let's work from there. In A68 mode, the variable is: [3] [3] [3] int a /* array of array of array of int */ 'a' decomposes to a reference to the first element, ie. ref [3] [3] int. Does it decompose further, although it's not an array anymore? Assume it does: now it's ref ref [3] int, and once more: ref ref ref int. And that's just 'a'. *a would be ref ref int, and **a would be ref int, and ***a would be an int (although the OP didn't go that far). Now you say that **a has type int[3] (or [3]int) and I say **a is ref int. (Which figures: in int b[3] then b decomposes to ref int when used in an expression). If all this is correct, then it's also completely crazy. Typically an int[3][3][3] would involve no pointers apart from it's static address. Yet the ***a expression implies there are 3 levels of pointers to dereference! I suppose they are just there to balance the &&&a[0][0][0] that the array decomposition rules apply. And I guess *a really means a[0]. Now it almost starts to make sense. Almost. -- Bart |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
CBFalconer <cbfalconer@yahoo.com> writes:
> Nikhil Bokare wrote: >> Thanks for pointing out my mistakes. This is my edited program: >> >> #include <stdio.h> >> >> int main() { >> int a[3][3][3]; >> printf("%p %p %p %p",a,*a,**a,&a); >> return 0; >> } >> >> Its still printing the same value for all of them. How does it >> happen?? > > Because you are still lying to printf and getting undefined > behaviour. %p requires a void* parameter. I also fixed your > #include statement. It's true that the above program lies to printf and thereby invokes undefined behavior. It's also true that one possible consequence of this undefined behavior is to print the same value four times. But it's almost certainly *not* true that the program prints the same value four times *because* it invokes undefined behavior. In most implementations, the behavior of passing a pointer value of a type other than void* to printf with a "%p" is exactly the same as the behavior of passing the same pointer value converted to void*. That's not guaranteed by the standard, of course, but it's very common. In the above program with that correction (casting all printf arguments after the format string to void* -- oh, yes, and adding a trailing "\n"), I would still expect it to print the same value four times. I'm not sure whether it's even possible for a conforming implementation *not* to print the same value four times. Yes, the program exhibits undefined behavior, and yes, that absolutely should be fixed, but that doesn't actually explain the behavior, and there is another explanation. There's nothing wrong with pointing out the undefined behavior *and then* answering the original question. In other words, why does *this* program print the same value four times? (I changed the spaces to new-lines to make it easier to see that all for values are the same.) #include <stdio.h> int main(void) { int a[3][3][3]; printf("%p\n%p\n%p\n%p\n", (void*)a, (void*)*a, (void*)**a, (void*)&a); return 0; } (My answer to that is "Read section 6 of the comp.lang.c FAQ".) -- Keith Thompson (The_Other_Keith) <kst-u@mib.org> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
Keith Thompson wrote:
> .... snip ... > > Yes, the program exhibits undefined behavior, and yes, that > absolutely should be fixed, but that doesn't actually explain > the behavior, and there is another explanation. There's > nothing wrong with pointing out the undefined behavior *and > then* answering the original question. Undefined behaviour can do _anything_. No explanation is needed. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
CBFalconer said:
> Keith Thompson wrote: >> > ... snip ... >> >> Yes, the program exhibits undefined behavior, and yes, that >> absolutely should be fixed, but that doesn't actually explain >> the behavior, and there is another explanation. There's >> nothing wrong with pointing out the undefined behavior *and >> then* answering the original question. > > Undefined behaviour can do _anything_. Agreed, but there's nothing wrong with pointing out the undefined behaviour *and then* answering the original question. > No explanation is needed. The OP needed an explanation. The fact that his program was flawed does not change this. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
"Nikhil Bokare" <nbokare@gmail.com> wrote in message
news:7315e312-e8ca-4f52-8810-360fb5a46e6c@l32g2000hse.googlegroups.com... > #include<stdio.h> > > int main() > { > int a[3][3][3]; > printf("%d %d %d %d",a,*a,**a,&a); > } > > I tried the above code and got the same value for a, *a , **a and &a. > Can anyone please tell me the reason behind such a behavior? http://web.torek.net/torek/c/pa.html |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
CBFalconer <cbfalconer@yahoo.com> writes:
> Keith Thompson wrote: > ... snip ... >> >> Yes, the program exhibits undefined behavior, and yes, that >> absolutely should be fixed, but that doesn't actually explain >> the behavior, and there is another explanation. There's >> nothing wrong with pointing out the undefined behavior *and >> then* answering the original question. > > Undefined behaviour can do _anything_. True. > No explanation is needed. Nonsense. It was obvious from the beginning that the OP was attempting to print the values of a, *a, **a, and &a, and wanted to know why they all appeared to have the same value. He clearly did require an explanation (i.e., he came to us for ), and digging through the undefined behavior to get to what he was actually asking about was easy enough that several of us managed to do it. A C program can behave in arbitrarily obnoxious ways in the presence of undefined behavior. We don't have to do likewise. -- Keith Thompson (The_Other_Keith) <kst-u@mib.org> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
Keith Thompson <kst-u@mib.org> writes:
> CBFalconer <cbfalconer@yahoo.com> writes: >> Keith Thompson wrote: >> ... snip ... >>> >>> Yes, the program exhibits undefined behavior, and yes, that >>> absolutely should be fixed, but that doesn't actually explain >>> the behavior, and there is another explanation. There's >>> nothing wrong with pointing out the undefined behavior *and >>> then* answering the original question. >> >> Undefined behaviour can do _anything_. > > True. > >> No explanation is needed. > > Nonsense. It was obvious from the beginning that the OP was > attempting to print the values of a, *a, **a, and &a, and wanted to > know why they all appeared to have the same value. He clearly did > require an explanation (i.e., he came to us for ), and digging > through the undefined behavior to get to what he was actually asking > about was easy enough that several of us managed to do it. > > A C program can behave in arbitrarily obnoxious ways in the presence > of undefined behavior. We don't have to do likewise. Mr CBFalconer does not seem happy unless he is being curt and rude to a new poster. I sometimes wonder why you can other more useful people even bother replying to his obnoxious nonsense. |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
"Ravishankar S" <ravishankar.s@in.bosch.com> wrote in message news:fo8r2q$emr$1@news4.fe.internet.bosch.com... > "Nikhil Bokare" <nbokare@gmail.com> wrote in message > news:7315e312-e8ca-4f52-8810-360fb5a46e6c@l32g2000hse.googlegroups.com... >> #include<stdio.h> >> >> int main() >> { >> int a[3][3][3]; >> printf("%d %d %d %d",a,*a,**a,&a); >> } >> >> I tried the above code and got the same value for a, *a , **a and &a. >> Can anyone please tell me the reason behind such a behavior? > > http://web.torek.net/torek/c/pa.html That's a pretty good link, especially http://web.torek.net/torek/c/expr.html#therule a bit further on. Text that tells you /about/ the language rather than try and teach you programming. [The 'rule'] "It falls out from a key fact: C does not have array values" Finally someone has pointed out the elephant in the drawing room, or whatever the saying is. -- Bart |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
In article <87d4rb3lqz.fsf@kvetch.smov.org>,
Keith Thompson <kst-u@mib.org> wrote: >CBFalconer <cbfalconer@yahoo.com> writes: >> Keith Thompson wrote: >> ... snip ... >>> >>> Yes, the program exhibits undefined behavior, and yes, that >>> absolutely should be fixed, but that doesn't actually explain >>> the behavior, and there is another explanation. There's >>> nothing wrong with pointing out the undefined behavior *and >>> then* answering the original question. >> >> Undefined behaviour can do _anything_. > >True. > >> No explanation is needed. > >Nonsense. It was obvious from the beginning that the OP was >attempting to print the values of a, *a, **a, and &a, and wanted to >know why they all appeared to have the same value. He clearly did >require an explanation (i.e., he came to us for ), and digging >through the undefined behavior to get to what he was actually asking >about was easy enough that several of us managed to do it. > >A C program can behave in arbitrarily obnoxious ways in the presence >of undefined behavior. We don't have to do likewise. Oh. The. Irony... |
|
|
|
#24 |
|
Messages: n/a
Hébergeur: |
Bartc wrote:
> "Ravishankar S" <ravishankar.s@in.bosch.com> wrote: > .... snip ... > >> http://web.torek.net/torek/c/pa.html > > That's a pretty good link, especially > http://web.torek.net/torek/c/expr.html#therule a bit further on. > > Text that tells you /about/ the language rather than try and > teach you programming. > > [The 'rule'] "It falls out from a key fact: C does not have array > values" Except that is wrong. However, C doesn't pass array values. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. -- Posted via a free Usenet account from http://www.teranews.com |
|
|
|
#25 |
|
Messages: n/a
Hébergeur: |
CBFalconer wrote:
> Bartc wrote: >> [The 'rule'] "It falls out from a key fact: C does not have array >> values" > > Except that is wrong. However, C doesn't pass array values. 6.3.2.1 Except when it is the operand of the sizeof operator, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue). This cannot happen with arrays. (Well, here "value" is what some people call a rvalue, but the standard does also define what the "value of a string" is.) -- Army1987 (Replace "NOSPAM" with "email") |
|
![]() |
| Outils de la discussion | |
|
|