I port the code from Turbo Pascal, and this feature is used: the variables are initialized in the data segment (typed consts), but then they are accessed by offsets like array, and not by identifiers. But FPС removes variables that are not explicitly accessed. Is it possible to change this behavior?
Hm... Your example doesn’t work for me... I look at the hex-codes of exe file, there are simply no bb/cc values, but it appears if I add the lines bb:=bb; cc:=cc;As Jonas said you're relying on undefined behavior. What are you trying to achieve with your code? Maybe we can help you find a better solution.
I renamed fpc.cfg (for no extra options), compile just "fpc filename.pas" — same result.
It's not FPC that removes them, but the linker.Indeed. When i compile as fpc -Aas or fpc -Awasm i got desired result.
What are you trying to achieve with your code? Maybe we can help you find a better solution.That software using Turbo Vision. In this library in order to save and load objects from files (saving current state, language resources) they need to be registered using records of the form
-Aas/-Awasm shows you the generated assembly code, not the linked binary. The data will always be in the assembly/object code. The linker runs afterwards and links all assembly code together. It's at that stage that unused code and data will be removed.`It's not FPC that removes them, but the linker.Indeed. When i compile as fpc -Aas or fpc -Awasm i got desired result.
That is undefined behaviour. It's not FPC that removes them, but the linker. If you want to access them as an array, you must define them as an array. Disabling smart linking may be able to get you the behaviour that you want but even then it could break at any time because linkers are also allowed to move data around.That may be the case, but at least for TP it proves to be well documented behavior. Not undefined. He has a definite point here and added the official TP manual entry. I checked that and tested it.
We cannot support emulating the TP or Delphi code generators or linkers. We are only compatible at the language level.That is undefined behaviour. It's not FPC that removes them, but the linker. If you want to access them as an array, you must define them as an array. Disabling smart linking may be able to get you the behaviour that you want but even then it could break at any time because linkers are also allowed to move data around.That may be the case, but at least for TP it proves to be well documented behavior. Not undefined. He has a definite point here and added the official TP manual entry. I checked that and tested it.
That is undefined behaviour. It's not FPC that removes them, but the linker...If you are using a Gnu linker then the option --undefined=symbolname can be used to stop the linker from discarding unreferenced symbols. Give the variables public names so that you don't have to worry about mangled names:
That is undefined behaviour. It's not FPC that removes them, but the linker...If you are using a Gnu linker then the option --undefined=symbolname can be used to stop the linker from discarding unreferenced symbols. Give the variables public names so that you don't have to worry about mangled names:
const a: word = $BB; public name 'a'; b: word = 13; public name 'b';
Then pass the following linker option via FPC:
fpc -k--undefined=a -k--undefined=b ...
Again: please do not try to hack this in. In FPC, this assumption is completely unreliable and can break at any time for various reasons (not just the linker).
In subject sources, unstead of calling hundred+ times of RegisterType, these records (like RDialog before) all are collected in a separate unit and are simply called in a loop:
A: TStreamRec = (... B: TStreamRec = (... ...more than hundred... Z: TStreamRec = (... var P: PStreamRec; I: Integer; begin P := @A; I :=Ofs(B) - Ofs(A); repeat RegisterType(P^); Inc(PtrRec(P).Ofs, I); until PtrRec(P).Ofs > Ofs(Z); end;
And because here explicitly used just three records, all the rest are missing in the binary obtained by FPC. That my current problem.
Ofs and Seg do not require any portability warnings, cause they work correctly in flat memory (segment 0 and address in that segment encompassing the whole address space).Again: please do not try to hack this in. In FPC, this assumption is completely unreliable and can break at any time for various reasons (not just the linker).
Jonas, do Seg() and Ofs() generate portability warnings from the compiler? IMO they should, and that should have been sufficient to warn OP that he was on very thin ice.
This will still not guarantee that the variables appear in the same order as in the source, even if that will usually be the case. Additionally, the OP is targeting Win32, which does not use the GNU Linker (I'm not sure we even support the GNU linker for that platform).Yes, the GNU linker still works, I last tested it when implementing the BigObj COFF format. To enable it the -Xe option needs to be used.
Yes, the GNU linker still works, I last tested it when implementing the BigObj COFF format. To enable it the -Xe option needs to be used.It seems that -Xe helps (alone, without public names). Executable size increased by ~40% but this is not a price.
Again: please do not try to hack this in. In FPC, this assumption is completely unreliable and can break at any time for various reasons (not just the linker).Maybe, but for now I’ll try with the ld.exe. If it will ultimately works, then why not...
Again: please do not try to hack this in. In FPC, this assumption is completely unreliable and can break at any time for various reasons (not just the linker).Maybe, but for now I’ll try with the ld.exe. If it will ultimately works, then why not...
Maybe, but for now I’ll try with the ld.exe. If it will ultimately works, then why not...
Thanks for help.