-2

This is a program in which a string "6" is passed to an integer variable y

#include<stdio.h>
void main()
{
    int x=0;
    int y=0;
    if(x==1)
        y=20;
    if(x==4)
        y=25;
    if(x==0)
        y="6"+10+x+y;
    printf("y= %d",y);
}

The output of this program is y= 4206638 which means here "6" is equal to 4206628. Can anyone tell me how is "6" equal to 4206628. If i replace "6" with some other character, the output is unaffected.

Faisal Nazir
  • 51
  • 1
  • 8
  • 2
    Ignoring UB ... you're misinterpreting what is being added... you cannot add integers and strings, your compiler assumes you know what you are doing and adds (still ignoring UB) address and integers. – pmg Apr 01 '21 at 07:39
  • 2
    The value of `"6"` is the address where it is stored. The numeric value it represents is `atoi("6")` but `atoi()` is not well recommended. – Weather Vane Apr 01 '21 at 07:39
  • Maybe you wanted to use `'6'` – Damien Apr 01 '21 at 07:39
  • 2
    What you got is the address of the string literal which you converted to an integer. Did your compiler show some warnings? If not, turn up warning level. For GCC you can use `-Wall -Wextra` to achieve that. – Gerhardh Apr 01 '21 at 07:40
  • 1
    As the comments mentioned before your edit, you are dealing with the address of the string, not with the content. Changing content will not necessarily change the address. Just as painting your front door in a new color will not change your living address. – Gerhardh Apr 01 '21 at 07:44

3 Answers3

2
y="6"+10+x+y;

With this line of code; the address of the string literal "6" is being assigned in memory to the int object i, which is in most cases undefined behavior because the value of a memory location is in many cases beyond the area an object of type int can hold.

This undefined value is then printed by:

printf("y= %d",y);

Moreover, we you would have observed the value won't be same everytime you run the code. The only issue is that when it casts a pointer to an integer, C compilers don't regard it as an error because a pointer (address in memory) is also a number (though in most situations "address number" overflows int) and you can print it in whatever format you want: decimal, hexadecimal, and so on. Also, the compiler must have given you a warning you doing so without an explicit cast; Something like:

warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]

Moral: We shouldn't ignore the warnings given by our smart compiler.

Atharva
  • 41
  • 4
  • 1
    "C compilers don't regard it as an error" The terms "compiler error" and "compiler warning" aren't defined by the C standard. See [What must a C compiler do when it finds an error?](https://software.codidact.com/posts/277340) In this case it _must_ display a diagnostic message. The implicit conversion from pointer to int is a non-standard extension. – Lundin Apr 01 '21 at 10:20
1

The problem is that you are either using a broken compiler or you are not paying attention to it.

"6" is a string literal in the form of an array placed in read-only memory. This array, like any array, "decays" into a pointer to the first element when used in an expression. So the "6"+10+x+y part is pointer arithmetic (using 1 byte characters), which in turn goes way beyond the end of that array and causes undefined behavior.

Then finally, you try to assign that strange, invalid pointer to an int. This isn't allowed by the C language, see "Pointer from integer/integer from pointer without a cast" issues.

The address will vary between different systems. You can run this well-defined code to see for yourself what's going on:

#include<stdio.h>
#include <stdio.h>
#include <stdint.h>

int main()
{
    int x=0;
    int y=0;

    printf("%p (address of \"6\")\n", (void*)"6");
    printf("+ 0x%x\n", 10+x+y);
    printf("= 0x%x\n", (uintptr_t)"6"+10+x+y);
}

I get this output:

0x402004 (address of "6")
+ 0xa
= 0x40200e

So why didn't the compiler give you an error for this invalid code? The reason: What must a C compiler do when it finds an error?

If you are a beginner learning C, then I strongly recommend that you compile like this (assuming gcc/clang/icc):

gcc -std=c11 -pedantic-errors -Wall -Wextra -Werror

This will block broken C code from resulting in a confusing, incorrect program getting built.

Lundin
  • 195,001
  • 40
  • 254
  • 396
1

When you define a string literal expression in C, a string is being created as an array in read only memory and a pointer is being passed back to the application. In this case, the variable stored in memory should be an ASCII number 6 followed by a null terminator (i.e. {0x36, 0x0}). However, in your program, the value used in your expression is actually the memory address for the first element of this array, so seeing a value of 4206638 makes a bit of sense.

If you were looking to use the ASCII value for number 6 (0x36) in your expression, you should use single quotes (i.e. '6'), which would pass back a signed integer 0x36, which is the ASCII representation of the number 6.

If you are looking to directly convert a string to an integer in C, you could use the standard library function atoi(), which receives a string pointer, such as the pointer returned in your application for string "6", and returns a signed integer.

Jonathon S.
  • 1,928
  • 1
  • 12
  • 18