Recent

Author Topic: Redeclared constant as variable  (Read 1843 times)

glorfin

  • Jr. Member
  • **
  • Posts: 61
Re: Redeclared constant as variable
« Reply #30 on: July 26, 2019, 02:35:14 pm »
same goes for
Code: Pascal  [Select]
  1. {$mode delphi}{$J+}
  2. // or
  3. {$mode objfpc}{$J+}

Yes, I checked all your variants. It worked in all of them. Only difference is that TP mode does not allow initialized variables.

ASerge

  • Hero Member
  • *****
  • Posts: 1390
Re: Redeclared constant as variable
« Reply #31 on: July 26, 2019, 03:29:55 pm »
So, Pascal typed constants are not really constant. ;D
In the new version it is the same as it was in Delphi 7:
Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3. {$WRITEABLECONST OFF}
  4. const
  5.   X: Integer = 1;
  6. var
  7.   P: PInteger;
  8. begin
  9.   P := @X;
  10.   P^ := 2; // Error SIGSEGV
  11.   Writeln(X);
  12. end.
With FPC 3.3.1 error, with FPC 3.0.4 - no.

440bx

  • Hero Member
  • *****
  • Posts: 1085
Re: Redeclared constant as variable
« Reply #32 on: July 26, 2019, 03:54:18 pm »
With FPC 3.3.1 error, with FPC 3.0.4 - no.
I just tried it with FPC 3.0.4 and I get a SIGSEGV as expected.  Did I misunderstand what you're saying ?
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 1390
Re: Redeclared constant as variable
« Reply #33 on: July 26, 2019, 04:45:16 pm »
Did I misunderstand what you're saying ?
You got me right. Just I tested only FPC x64. It turns out in FPC 3.0.4 x32, too, error.

440bx

  • Hero Member
  • *****
  • Posts: 1085
Re: Redeclared constant as variable
« Reply #34 on: July 26, 2019, 04:49:28 pm »
You got me right. Just I tested only FPC x64. It turns out in FPC 3.0.4 x32, too, error.
I get the SIGSEGV in both x64 and X32.   You only get it in x64 ?  (that would be strange...)
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 1390
Re: Redeclared constant as variable
« Reply #35 on: July 26, 2019, 05:05:40 pm »
You only get it in x64 ?  (that would be strange...)
SIGSEGV on FPC 3.0.4 x32, FPC 3.3.1 x64. No erorr FPC 3.0.4 x64.

440bx

  • Hero Member
  • *****
  • Posts: 1085
Re: Redeclared constant as variable
« Reply #36 on: July 26, 2019, 05:32:01 pm »
No erorr FPC 3.0.4 x64.
I get the access violation in both 32 and 64bit.  I wonder why you don't get it in x64.  That's strange.

Have you looked at the assembly code generated for x64 ?... there might be a clue there why you are not getting the access violation.

using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 1390
Re: Redeclared constant as variable
« Reply #37 on: July 26, 2019, 05:50:15 pm »
Have you looked at the assembly code generated for x64 ?... there might be a clue there why you are not getting the access violation.
Yes, the strange thing is that I usually compile with the "-a" key to see the assembler code. It turned out that this is the reason.
Quote
C:\Temp>fpc test.lpr
Free Pascal Compiler version 3.0.4 [2019/04/13] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling test.lpr
Linking test.exe
11 lines compiled, 0.1 sec, 31104 bytes code, 1332 bytes data

C:\Temp>test.exe
Runtime error 216 at $0000000100001477
  $0000000100001477


C:\Temp>fpc -a test.lpr
Free Pascal Compiler version 3.0.4 [2019/04/13] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Note: Switching assembler to default source writing assembler
Target OS: Win64 for x64
Compiling test.lpr
Assembling program
Linking test.exe
11 lines compiled, 0.1 sec, 31104 bytes code, 1348 bytes data
1 note(s) issued

C:\Temp>test.exe
2

C:\Temp>

ASerge

  • Hero Member
  • *****
  • Posts: 1390
Re: Redeclared constant as variable
« Reply #38 on: July 26, 2019, 05:53:55 pm »
Forgot the assembler:
Code: ASM  [Select]
  1. ...
  2.         leaq    TC_$P$PROGRAM_$$_X(%rip),%rax
  3.         movq    %rax,U_$P$PROGRAM_$$_P(%rip)
  4.         movq    U_$P$PROGRAM_$$_P(%rip),%rax
  5.         movl    $2,(%rax)
  6. ...
  7. .section .bss
  8.         .balign 8
  9. U_$P$PROGRAM_$$_P:
  10.         .zero 8

440bx

  • Hero Member
  • *****
  • Posts: 1085
Re: Redeclared constant as variable
« Reply #39 on: July 26, 2019, 06:07:08 pm »
It turned out that this is the reason.
That looks like a bug.  When requesting the assembler listing, does it put the X constant in a different segment than when the listing is not requested ?

IOW, it seems the only way for the access violation not to occur is for X to be in a writeable data segment (such as .bss)
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 8673
Re: Redeclared constant as variable
« Reply #40 on: July 26, 2019, 06:26:52 pm »
I think the cause is that typed consts in {$J-} state are stored into the read-only section during link-time. If that's the case it is not a bug but an actual improvement.
I also think that behavior is documented in the changes trunk (but it made 3.2.0)
Ask on the devel list if I am correct. I am not quite sure.
« Last Edit: July 26, 2019, 06:28:46 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

PascalDragon

  • Hero Member
  • *****
  • Posts: 564
  • Compiler Developer
Re: Redeclared constant as variable
« Reply #41 on: July 27, 2019, 10:59:09 am »
So, Pascal typed constants are not really constant. ;D
As the others already showed in their recent posts this is the case in current FPC versions with $J-.

Forgot the assembler:
Code: ASM  [Select]
  1. ...
  2.         leaq    TC_$P$PROGRAM_$$_X(%rip),%rax
  3.         movq    %rax,U_$P$PROGRAM_$$_P(%rip)
  4.         movq    U_$P$PROGRAM_$$_P(%rip),%rax
  5.         movl    $2,(%rax)
  6. ...
  7. .section .bss
  8.         .balign 8
  9. U_$P$PROGRAM_$$_P:
  10.         .zero 8
It's not P you need to look at, but X. Here is what current 3.3.1 one generates with -al:
Code: ASM  [Select]
  1. # Begin asmlist al_rotypedconsts
  2.  
  3. .section .rodata.n_TC_$P$TMW_$$_X,"d"
  4.         .balign 2
  5. TC_$P$TMW_$$_X:
  6.         .short  42
  7. # [42] var
  8. # End asmlist al_rotypedconsts
So as you can see it's placed into a read only section. And it bombs in both cases, -al and no -al. ;)

Note: Please note that it might not be the case on all platforms that constants are placed into a readonly section as the platform might not support the concept. FPC does it where supported.

Thaddy

  • Hero Member
  • *****
  • Posts: 8673
Re: Redeclared constant as variable
« Reply #42 on: July 27, 2019, 12:26:42 pm »
Summary:
const: will be replaced by the compiler with a literal value if possible, otherwise stored in read-only section
typed const in $J- state:always stored in read-only section. This means it is a true constant, but as opposed to the above, always has a memory location.
typed const in $J+ state:always stored in read-write section. The C/C++ equivalent is a static var, nothing to do with a C const.
Also note $J+ and $J- can be mixed in the same unit. (use $push/$pop),
« Last Edit: July 27, 2019, 12:39:36 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

Peter H

  • Jr. Member
  • **
  • Posts: 52
Re: Redeclared constant as variable
« Reply #43 on: July 27, 2019, 01:06:39 pm »
Yes, thank you, it works, I tried it in FPC 3.0.4.

Especially intermixing J- and J+ works.
And at compile time the compiler knows, what is writable and what is not.

This doesnt mean that I like the nomenclature, "writable constant" is an oxymoron.
Such a thing like this should not be in an ISO Standard. They should have made a new keyword, "static" for this purpose.

Nothing lives longer than an improvisorium!

Of course I understand the need of Delphi compatibility, and because static variables nowadays are rarely needed it is not of big importance.

Thaddy

  • Hero Member
  • *****
  • Posts: 8673
Re: Redeclared constant as variable
« Reply #44 on: July 27, 2019, 01:23:35 pm »
@Peter H
If you must you can do this:
Code: Pascal  [Select]
  1. program static;
  2. {$mode objfpc}{$macro on}{$define static_var:={$J+}const }  // equivalent of C notated static var
  3. {$push}
  4. static_var a:integer = 200;
  5. {$pop}
  6. begin
  7.   inc(a);
  8.   writeln(a);
  9. end.
But you have to decorate the macro yourself with {$push} and {$pop} as I show here, unless you want writable consts to be global.
This is not Delphi compatible: Delphi has no macro language.
« Last Edit: July 27, 2019, 01:37:24 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.