Can const_cast do change the constant in c/c++ ? No, in c/c++ const is const, and never change.

Consider below simple codes, what is the correct output ?

#include <stdio.h>

int main() {
  const int constant = 300;
  int* modifier = const_cast<int*>(&constant);
  printf("%d\n", constant);
  *modifier = 100;
  printf("%d\n", *modifier);
  printf("%d\n", constant);
  return 0;
}




You might think we already use const_cast and change the value to 100,
The output should be like:
300
100
100

No, That is wrong, the real output is :
300
100
300

oh, why the contant did not change? Are modifier and constant not pointed to same address ? 
ok. let's print out the pointed address to check it:
#include <stdio.h>

int main() {
  const int constant = 300;
  int* modifier = const_cast<int*>(&constant);
  printf("%d\n", constant);
  *modifier = 100;
  printf("%d\n", *modifier);
  printf("%d\n", constant);

  printf("constant %p modifier %p\n", &
constant, modifier);

   return 0;
}

let's see what we get:
300
100

300
constant 0x7ffc62b04164 modifier 0x7ffc62b04164

oh they are same exactly. so it is very strange.
Is it possible that different value for same address ?
No, it is impossible. It seems someone make the const in compiling time.

To figure out why constant do not change, let's goto disassemble.
save the codes to c.c
gcc -o c c.c
objdump -d c
Then let's check the main function:
000000000040052d <main>:
  40052d:       55                      push   %rbp
  40052e:       48 89 e5                mov    %rsp,%rbp
  400531:       48 83 ec 10             sub    $0x10,%rsp
  400535:       c7 45 f4 2c 01 00 00    movl   $0x12c,-0xc(%rbp)
  40053c:       48 8d 45 f4             lea    -0xc(%rbp),%rax
  400540:       48 89 45 f8             mov    %rax,-0x8(%rbp)
  400544:       be 2c 01 00 00          mov    $0x12c,%esi
  400549:       bf 34 06 40 00          mov    $0x400634,%edi
  40054e:       b8 00 00 00 00          mov    $0x0,%eax
  400553:       e8 b8 fe ff ff          callq  400410 <printf@plt>

  400558:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  40055c:       c7 00 64 00 00 00       movl   $0x64,(%rax)
  400562:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  400566:       8b 00                   mov    (%rax),%eax
  400568:       89 c6                   mov    %eax,%esi
  40056a:       bf 34 06 40 00          mov    $0x400634,%edi
  40056f:       b8 00 00 00 00          mov    $0x0,%eax
  400574:       e8 97 fe ff ff          callq  400410 <printf@plt>

  400579:       be 2c 01 00 00          mov    $0x12c,%esi
  40057e:       bf 34 06 40 00          mov    $0x400634,%edi
  400583:       b8 00 00 00 00          mov    $0x0,%eax
  400588:       e8 83 fe ff ff          callq  400410 <printf@plt>

  40058d:       48 8b 55 f8             mov    -0x8(%rbp),%rdx
  400591:       48 8d 45 f4             lea    -0xc(%rbp),%rax
  400595:       48 89 c6                mov    %rax,%rsi
  400598:       bf 38 06 40 00          mov    $0x400638,%edi
  40059d:       b8 00 00 00 00          mov    $0x0,%eax
  4005a2:       e8 69 fe ff ff          callq  400410 <printf@plt>
  4005a7:       b8 00 00 00 00          mov    $0x0,%eax
  4005ac:       c9                      leaveq
  4005ad:       c3                      retq
  4005ae:       66 90                   xchg   %ax,%ax




As you can the purple assemble codes(printf("%d\n", constant);):
  400579:       be 2c 01 00 00          mov    $0x12c,%esi
  40057e:       bf 34 06 40 00          mov    $0x400634,%edi
  400583:       b8 00 00 00 00          mov    $0x0,%eax
  400588:       e8 83 fe ff ff          callq  400410 <printf@plt>

The assemble use 0x12c(means 300 in dec) directly.

It seems the compiler treat const like macro and expand it while compile.
To summary, const is somehow same to define macros.
const int constant = 300;  <==> #define constant 300


No comments:

Post a Comment

fixed: embedded-redis: Unable to run on macOS Sonoma

Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...