I have executed the below programm on both C and C++ compiler and got different results

#include <stdio.h>
int main() 
{
 const int a=10;
 int *p=(int*)(&a); 
 *p = 20;
    printf("address of a=%u\t%d\n", &a,a);
    printf("address of p=%u\t%d\n", p,*p);
    return 0;
}

With C compiler I got the output
address of a=1245052 20
address of p=1245052 20

With C++ compiler I got
address of a=1245052 10
address of p=1245052 20

Can anybody tell me why the different value for *p and a even thiough both are pointing to the same memory location?

Comments
Good Question

I think you are encountering what is commonly called "undefined behavior" or "implemention specific". In C, const int a points to a memory location that can be modified, but in c++ variable a is not located at any memory variable but just used as an immediate value, which is similar to just hard-coding a literal value in the program. You could have rewritten the lines like this:

c++
 printf("address of a=%u\t%d\n", &a,10);

c
 printf("address of a=%u\t%d\n", &a,a);

Can you tell me where the variable be put when it is declared as const. Will it go into const segment.

"You can also specify sections for initialized data (data_seg), functions (code_seg), and const variables (const_seg)."

The above is an extract from msdn. If it goes into a particular segment of memory, why the value is not getting changed when modified thru a pointer.
From your expalnation what I understood is that the const variable is replaced by the value whenever it is encountered by the compiler.
i.e it is not stored at a specific location.

Now if I use C compiler why is the value getting changed or why it is behaving differently?

Actually the memory location for a does get modified in Visual C++. But this is implementation specific. It may not be so in gcc. But the catch is that Visual C++ never uses the value stored in a 's memory location. It is allowed to do so by the C++ standard. That is because if you declare a as const int , that means you are never going to change it's value. So as an optimization, the compiler can use the literal directly instead of the actual value stored in a . You can see this fact if you take a look at the assembly code for your program.

I have attached the assembly files in text format and line 7 is the relevant portion.


CPP Assembly

; Line 7
    push    10                  ; 0000000aH
    lea edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG611
    call    _printf
    add esp, 12                 ; 0000000cH

The code in red just pushes the literal 10 to the stack. Not the contents of a . So the contents of a will NOT be displayed.


C Assembly

; Line 7
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    lea eax, DWORD PTR _a$[ebp]
    push    eax
    push    OFFSET FLAT:$SG795
    call    _printf
    add esp, 12                 ; 0000000cH

The code in red loads the contents of a to edx , and then pushes the contents in edx to the stack. So the contents in a will be displayed.

Attachments
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077 

	TITLE	test.cpp
	.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA	ENDS
CONST	SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST	ENDS
_BSS	SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS	ENDS
$$SYMBOLS	SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS	ENDS
_TLS	SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS	ENDS
FLAT	GROUP _DATA, CONST, _BSS
	ASSUME	CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

CONST	SEGMENT
$SG611	DB	'address of a=%u', 09H, '%d', 0aH, 00H
$SG612	DB	'address of p=%u', 09H, '%d', 0aH, 00H
CONST	ENDS
PUBLIC	_main
EXTRN	_printf:NEAR
; Function compile flags: /Odt
_TEXT	SEGMENT
_a$ = -8						; size = 4
_p$ = -4						; size = 4
_main	PROC NEAR
; File i:\my code\c++\test.cpp
; Line 3
	push	ebp
	mov	ebp, esp
	sub	esp, 8
; Line 4
	mov	DWORD PTR _a$[ebp], 10			; 0000000aH
; Line 5
	lea	eax, DWORD PTR _a$[ebp]
	mov	DWORD PTR _p$[ebp], eax
; Line 6
	mov	ecx, DWORD PTR _p$[ebp]
	mov	DWORD PTR [ecx], 20			; 00000014H
; Line 7
	push	10					; 0000000aH
	lea	edx, DWORD PTR _a$[ebp]
	push	edx
	push	OFFSET FLAT:$SG611
	call	_printf
	add	esp, 12					; 0000000cH
; Line 8
	mov	eax, DWORD PTR _p$[ebp]
	mov	ecx, DWORD PTR [eax]
	push	ecx
	mov	edx, DWORD PTR _p$[ebp]
	push	edx
	push	OFFSET FLAT:$SG612
	call	_printf
	add	esp, 12					; 0000000cH
; Line 9
	xor	eax, eax
; Line 10
	mov	esp, ebp
	pop	ebp
	ret	0
_main	ENDP
_TEXT	ENDS
END
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077 

	TITLE	test.cpp
	.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA	ENDS
CONST	SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST	ENDS
_BSS	SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS	ENDS
$$SYMBOLS	SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS	ENDS
_TLS	SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS	ENDS
FLAT	GROUP _DATA, CONST, _BSS
	ASSUME	CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

_DATA	SEGMENT
$SG795	DB	'address of a=%u', 09H, '%d', 0aH, 00H
$SG796	DB	'address of p=%u', 09H, '%d', 0aH, 00H
_DATA	ENDS
PUBLIC	_main
EXTRN	_printf:NEAR
; Function compile flags: /Odt
_TEXT	SEGMENT
_a$ = -8						; size = 4
_p$ = -4						; size = 4
_main	PROC NEAR
; File i:\my code\c++\test.cpp
; Line 3
	push	ebp
	mov	ebp, esp
	sub	esp, 8
; Line 4
	mov	DWORD PTR _a$[ebp], 10			; 0000000aH
; Line 5
	lea	eax, DWORD PTR _a$[ebp]
	mov	DWORD PTR _p$[ebp], eax
; Line 6
	mov	ecx, DWORD PTR _p$[ebp]
	mov	DWORD PTR [ecx], 20			; 00000014H
; Line 7
	mov	edx, DWORD PTR _a$[ebp]
	push	edx
	lea	eax, DWORD PTR _a$[ebp]
	push	eax
	push	OFFSET FLAT:$SG795
	call	_printf
	add	esp, 12					; 0000000cH
; Line 8
	mov	ecx, DWORD PTR _p$[ebp]
	mov	edx, DWORD PTR [ecx]
	push	edx
	mov	eax, DWORD PTR _p$[ebp]
	push	eax
	push	OFFSET FLAT:$SG796
	call	_printf
	add	esp, 12					; 0000000cH
; Line 9
	xor	eax, eax
; Line 10
	mov	esp, ebp
	pop	ebp
	ret	0
_main	ENDP
_TEXT	ENDS
END

Your explanation was very usefull. I have one more doubt in the same context.

This assembly thing is quite new for me. In the cpp assembly line 7 states push 10.
So does that mean in Cpp the constant variable are also pushed onto the stack?????

I can't say anything about cpp. That is not specified in the standard. It only happens in Visual C++. It may be different in gcc. But in VC++, the variable is not pushed into the stack. Only the literal it holds. In this case it is 10.

This article has been dead for over six months. Start a new discussion instead.