|
|
||||
|
||||
|
|
|
|||
|
On 6/8/2012 10:52 AM, rage wrote:
> Can someone please help me out on this? > > #include<stdio.h> > main() > { > int i; > int *j=10; What are you trying to accomplish with this line? Your compiler should have given you a diagnostic message about it; what did the message say, and what meaning did you think it had? > i=j+19; Should have received another diagnostic message for this line. > printf("%d %d\n",j,i); No diagnostic is *required* for this line, but some compilers are smart and helpful enough to issue one. > } > > The output is a garbage value (86) on my pc and ideone. Should it not be 29? Your code's behavior is undefined, so there is no reason you "should" expect any particular output, nor even any output at all. What are you trying to do? -- Eric Sosman esosman@ieee-dot-org.invalid |
|
|||
|
On 2012-06-08, rage <hansum.rahul@gmail.com> wrote:
> Can someone please help me out on this? Your code is not a well-formed ISO C program. It contains type system violations that require a diagnostic. > #include<stdio.h> > main() > { > int i; > int *j=10; Here, a variable of pointer type is being initialized with an integer value. > i=j+19; Here, an integer object is being assigned from a pointer expression. > printf("%d %d\n",j,i); Here, the %d conversion specifier, which requires a matching argument of type int, is given an argument of type "int *". This is undefined behavior. > } > > The output is a garbage value (86) on my pc and ideone. Should it not be 29? Since the program requires diagnostics, the ISO C standard doesn't require the implementation to translate and execute the program. If the program translates and executes anyway, its behavior is not defined by ISO C. Of course, it has a behavior, but implementation-specific reasoning is required to understand it. For instance, whether or not you can print a pointer using %d will depend on the calling conventions, and that can be sensitive to different versions of even the same compiler. What if pointers are 64 bits wide but int is 32 bits? In that case it is conceivable that "%d %d" will just take two halves of the 64 bit j value, and i is ignored. This kind of program is usually not correct even according to the local compiler and library documentation, never mind ISO C. |
|
|||
|
On 2012-06-08, rage <hansum.rahul@gmail.com> wrote:
> Can someone please help me out on this? > > #include<stdio.h> > main() > { > int i; > int *j=10; In this line, you're converting an integer value to a pointer. That is an operation with undefined behavior. (Except if the integer is a constant value of zero, if I recall right.) Because of this undefined behavior, your program may not compile at all. Even if it does, it may not run. Even if it runs, it may not give any sensible output. Undefined behavior basically means "sorry mate, you're on your own here". Do you actually know what pointers are? If not, I'd recommend not using the unary & and * operators until you do. -- "C provides a programmer with more than enough rope to hang himself. C++ provides a firing squad, blindfold and last cigarette." - seen in comp.lang.c |
|
|||
|
On 06/08/2012 10:52 AM, rage wrote:
> Can someone please help me out on this? > > #include<stdio.h> > main() > { > int i; > int *j=10; You're trying to initializing j, which is a pointer to an int, with the value of 10, which is an integer. That's a constraint violation (6.5.16.1p1). A conforming implementation is required to issue a diagnostic message - did yours? If so, what did it say? After issuing the diagnostic, your compiler is free to do anything it wants with your code. I suspect that what it is doing is converting 10 to a pointer value, and storing that pointer value in j. You could force it to do that conversion explicitly by inserting an (int*) before the 10, in which case the constraint violation would go away. However, the resulting pointer value is implementation-defined. It might contain a trap representation, in which case the behavior of your program would still be undefined. Even if it is not a trap representation, you have no idea where in memory it points at. It probably does not point at a piece of memory reserved for use by your program; if it does, there's a small chance it points at the same piece of memory reserved to store the value of 'i'. > i=j+19; Since you don't know what location in memory j points at, you can't be sure whether adding 19 to that pointer will have defined behavior; it probably doesn't. You're trying to store the result of that addition, which is a pointer value, into an int object. This is once again a constraint violation, with the same consequences as the first time. > printf("%d %d\n",j,i); You're using a %d format specifier, which should be used only for int values, to print the value of j, which is a pointer. That's yet another example of undefined behavior. > } > > The output is a garbage value (86) on my pc and ideone. Should it not be 29? The output could have been anything, including the text of the "Star Spangled Banner" (or nothing at all). That's what "undefined behavior" means. Here's correct code that does something similar to what your original code may have been meant to do: int i; int k; int *j=&k; *j = 10; i = *j+19; printf("%d %d\n", *j, i); |
|
|||
|
"rage" <hansum.rahul@gmail.com> wrote in message news:7081cbd2-1ff6-4591-89c0-e7680b330790@googlegroups.com... > Can someone please help me out on this? > > #include<stdio.h> > main() > { > int i; > int *j=10; > i=j+19; > printf("%d %d\n",j,i); > } > > The output is a garbage value (86) on my pc and ideone. Should it not be > 29? Assuming you did intend j to be a pointer, try it like this: #include<stdio.h> #include<stdlib.h> int main(void) { int i; int *j=malloc(sizeof(int)); *j=10; i=*j+19; printf("%d %d\n",*j,i); } (The code assumes the malloc() call is successful.) -- Bartc |
|
|||
|
In <7081cbd2-1ff6-4591-89c0-e7680b330790@googlegroups.com> rage <hansum.rahul@gmail.com> writes:
> Can someone please help me out on this? > #include<stdio.h> > main() > { > int i; > int *j=10; > i=j+19; > printf("%d %d\n",j,i); > } > The output is a garbage value (86) on my pc and ideone. Should it not be 29? You declared j as an integer pointer, and initialized it to point at memory location 10, which very likely contains an unknown value. As others have said, your compiler should have issued a warning about this, which would have given you a clue as to what the problem was. -- John Gordon A is for Amy, who fell down the stairs gordon@panix.com B is for Basil, assaulted by bears -- Edward Gorey, "The Gashlycrumb Tinies" |
|
|||
|
"rage" <hansum.rahul@gmail.com> ha scritto nel messaggio news:7081cbd2-1ff6-4591-89c0-e7680b330790@googlegroups.com... > Can someone please help me out on this? > > #include<stdio.h> > main() > { > int i; > int *j=10; > i=j+19; > printf("%d %d\n",j,i); > } > > The output is a garbage value (86) on my pc and ideone. Should it not be 29? no it shuould be 10+[sizeof(int*) * 19] if it is sizeof(int*)==4 than 10+[4 * 19] = 86 because it appear in j+19 "19" mean 19*sizeof(type(j)) '+' follow the aritmetic on array of element size sizeof(int*) so if p is a pointer that point to something of size M p+19 means p+M*19 as address in char obj yes i know it is UB but in the place is not as above "10+[sizeof(int*) * 19] " i think it is weak, something is not based from math... on what?? |
|
|||
|
"io_x" <a@b.c.invalid> ha scritto nel messaggio news:4fd22dcb$0$1388$4fafbaef@reader2.news.tin.it. .. > > "rage" <hansum.rahul@gmail.com> ha scritto nel messaggio > news:7081cbd2-1ff6-4591-89c0-e7680b330790@googlegroups.com... >> Can someone please help me out on this? >> >> #include<stdio.h> >> main() >> { >> int i; >> int *j=10; >> i=j+19; >> printf("%d %d\n",j,i); >> } >> >> The output is a garbage value (86) on my pc and ideone. Should it not be 29? > > no it shuould be 10+[sizeof(int*) * 19] > if it is sizeof(int*)==4 > than 10+[4 * 19] = 86 > because it appear in j+19 "19" mean 19*sizeof(type(j)) > '+' follow the aritmetic on array of > element size sizeof(int*) > > so if p is a pointer that point to something of size M > p+19 means p+M*19 as address in char obj > > yes i know it is UB > but in the place is not as above "10+[sizeof(int*) * 19] " > i think it is weak, something is not based from math... > on what?? in all above speach swap("sizeof(int*)", "sizeof(int)") swap("sizeof(type(j))", "sizeof(type(*j))") |
|
|||
|
rage wrote:
> Can someone please help me out on this? > > #include<stdio.h> > main() > { > int i; > int *j=10; > i=j+19; > printf("%d %d\n",j,i); > } > > The output is a garbage value (86) on my pc and ideone. Should it not be 29? > Your code is broken: int i; int k = 10; int *j = &k; i=(*j)+19; printf("%d %d\n",*j,i); might work as you expect. "int *j;" declares j as "a pointer to an integer". "j = 10;" make it point to address 10. you probably don't want that. From that point on, you're not in Kansas any more.. you're exposing... <puts on sunglasses> UNDEFINED BEHAVIOR! -- Les Cargill |
|
|||
|
Angel <angel+news@spamcop.net> writes:
> On 2012-06-08, rage <hansum.rahul@gmail.com> wrote: >> Can someone please help me out on this? >> >> #include<stdio.h> >> main() >> { >> int i; >> int *j=10; > > In this line, you're converting an integer value to a pointer. That > is an operation with undefined behavior. (Except if the integer is a > constant value of zero, if I recall right.) What makes you think there's a conversion there? The declaration violates a constraint. An initialization has the same constraints as a simple assignment (N1570 6.7.9p11). The rules for simple assignment say that if the left hand side has pointer type, the right hand side must have pointer type (either a compatible type or void*) or it can be a null pointer constant. Since int *j = 10; doesn't satisfy these constraints, there is no definition of its behavior. In particular, the standard does not say or imply that the int value 10 should be converted to int*. That was the typical behavior for pre-standard versions of C, and most compilers that don't reject the declaration will generate code equivalent to: int *j = (int*)10; But it's not required. Note that the behavior of an integer-to-pointer conversion is not (entirely) undefined. N1570 6.3.2.3 says: An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation. with a footnote: The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment. (But that's not relevant to this code because, as I said, no conversion is implied.) [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|||
|
rage <hansum.rahul@gmail.com> writes:
> Can someone please help me out on this? > > #include<stdio.h> > main() > { > int i; > int *j=10; > i=j+19; > printf("%d %d\n",j,i); > } > > The output is a garbage value (86) on my pc and ideone. Should it not be 29? The value 86 is not garbage, though the program that produced it is. First off, "main()" should be "int main(void)". Most compilers will probably accept "main()", but it's an obsolete form. int *j = 10; is a constraint violation. Your compiler should have either produced a warning or rejected it outright, and you should have told us that. If your compiler doesn't produce a diagnostic, then it's misbehaving; find out how to invoke it so that it produces proper diagnostics. If it's not rejected, the most likely behavior is that the compiler will treat it as if you had written: int *j = (int*)10; which converts the int value 10 to int* and stores it in j. This is almost certainly a nonsensical thing to do, but it's legal; the result of the conversion is implementation-defined. i = j + 19; Since j is a pointer object, j + 19 performs pointer arithmetic. Given a pointer value p and an integer value n, the expression p + n assumes that p points to an element of an array and yields a pointer n elements past the one that p points to. In other words, pointer arithmetic is scaled by the size of the pointed-to type. If sizeof (int) == 4 on your system, then j + 19 is likely to yield a pointer to a location 76 bytes (19 int objects) past the location that j points to. printf("%d %d\n", j, i); This has undefined behavior. The "%d" format requires an int argument, but you're giving it an int*. But given a few plausible assumptions, such as that int and int* happen to have the same size and that conversions between pointers and integers just reinterpret the representation without performing any other transformation, it's likely that it will print 10 89 where 10 is the value of j (10 converted from int to int*, and the interpreted as if it were an int), and 89 is the value of i (10 + (4*19), but with several conversions from int to int* and back again). The only thing you really *need* to know about this program is that it's invalid. You have several instances of undefined behavior, and one constraint violation, requiring a compile-time diagnostic that *you should not ignore*. The above is a plausible explanation of the behavior you're seeing -- but it could be completely different on another system, or on the same system with different options, or it could be rejected altogether. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|||
|
On 2012-06-08, Keith Thompson <kst-u@mib.org> wrote:
> Angel <angel+news@spamcop.net> writes: >> On 2012-06-08, rage <hansum.rahul@gmail.com> wrote: >>> Can someone please help me out on this? >>> >>> #include<stdio.h> >>> main() >>> { >>> int i; >>> int *j=10; >> >> In this line, you're converting an integer value to a pointer. That >> is an operation with undefined behavior. (Except if the integer is a >> constant value of zero, if I recall right.) > > What makes you think there's a conversion there? > > The declaration violates a constraint. An initialization has > the same constraints as a simple assignment (N1570 6.7.9p11). > The rules for simple assignment say that if the left hand side has > pointer type, the right hand side must have pointer type (either > a compatible type or void*) or it can be a null pointer constant. > > Since > > int *j = 10; > > doesn't satisfy these constraints, there is no definition of its > behavior. In particular, the standard does not say or imply that the > int value 10 should be converted to int*. > > That was the typical behavior for pre-standard versions of C, and > most compilers that don't reject the declaration will generate code > equivalent to: > > int *j = (int*)10; > > But it's not required. > > Note that the behavior of an integer-to-pointer conversion is not > (entirely) undefined. N1570 6.3.2.3 says: > > An integer may be converted to any pointer type. Except as > previously specified, the result is implementation-defined, > might not be correctly aligned, might not point to an entity > of the referenced type, and might be a trap representation. > > with a footnote: > > The mapping functions for converting a pointer to an integer > or an integer to a pointer are intended to be consistent with > the addressing structure of the execution environment. > > (But that's not relevant to this code because, as I said, no conversion > is implied.) Haha, thanks for clarifying and correcting. Clearly I've been out of C programming so much that what I know no longer matches with current standards. I suppose I should go brush up my skills. :-) Anyway, the bottom line to the original poster is "don't mix up integers and pointers unless you really know what you're doing", yes? -- "C provides a programmer with more than enough rope to hang himself. C++ provides a firing squad, blindfold and last cigarette." - seen in comp.lang.c |
|
|||
|
Angel <angel+news@spamcop.net> writes:
[...] > Anyway, the bottom line to the original poster is "don't mix up integers > and pointers unless you really know what you're doing", yes? Pretty much. Conversions between pointers and integers are problematic (except for the special case of converting a null pointer constant, such as a literal 0, to a pointer type, which is well defined). On the other hand, pointer arithmetic is well defined in most cases: pointer + integer => pointer integer + pointer => pointer pointer - pointer => integer (except that it doesn't apply to void* or other pointers to incomplete types, or to function pointers, and going outside the bounds of a single object is undefined.) -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|