My position is that constants aren't said to be write-once, and you call that indefensible?!
No. I didn't call that indefensible. And you know it. That's just a(nother) poor & unworthy attempt at diversion.
Constants are 'set' when they are constructed.
There is no such thing as "construction time" for a constant. Only 'compile-time'. Vis:
#! perl -slw
use strict;
use constant FRED => 12345;
print FRED;
undef *FRED;
print FRED;
__END__
C:\test>junk84
12345
12345
Even though the subroutine FRED() has been deleted (at runtime), the subsequent print of the constant FRED still works and displays the correct value.
This, as you know, is because the opcode to call to the subroutine FRED() is replaced with an opcode that embeds the value that would have been returned by that subroutine directly into the opcode tree. At compile time!
So even though the subroutine no longer exists, at runtime, when the second print statement is executed, the value is still there embedded in the opcode tree.
On the other hand, variables, including read-only object instance variables are only assigned their values when they are constructed. At runtime.
But more importantly, whenever a variable, including read-only variables, is referenced, its SV has to be dereferenced; it flags have to be checked, conversions from PV to IV or vice versa have to be performed as appropriate. Each and every time it is referenced.
Whereas constants are embedded right there in the opcode tree.
In neither case can you choose to write later.
You're pretending you have no knowledge of Internals::SetReadWrite()?
Are you gonna start calling read-only memory pages write-once too?
No. Of course I'm not. Indefensible statements are your MO, not mine. Another straw man disappears in a puff on smoke.
What about constant parameters and constant variables in C? All three are constructed at run-time.
What utter drivel.
- C language constants are 'constructed' by the compiler at compile-time and written to the object files in named and marked read-only data segments.
- These well-known named segments from different object files are amalgamated together and written as pre-populated memory images to the process executable file, by the linker at link-time.
- The executable image file is mapped into the virtual address space by the system loader at load-time.
- The system loader then adds the process structure to the system scheduler's dispatch table.
- At some point in the future, the process will get a timeslot, the CRT will be initialised; and the programs main() entrypoint will be called.
- At some point after that, the processes instruction counter will be incremented to a point that will cause the appropriate page of the process image to be loaded into the cache.
There is no 'construction-time' element involved. No runtime element involved. All the work was done (once) at compile-time and link-time and load-time.
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00
+.21022.08
include listing.inc
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
_DATA SEGMENT
$SG695 DB '%I64u', 0aH, 00H
_DATA ENDS
PUBLIC main
EXTRN printf:PROC
pdata SEGMENT
$pdata$main DD imagerel $LN3
DD imagerel $LN3+43
DD imagerel $unwind$main
pdata ENDS
xdata SEGMENT
$unwind$main DD 010401H
DD 06204H
; Function compile flags: /Odtp
xdata ENDS
_TEXT SEGMENT
x$ = 32
main PROC
; File c:\test\proof.c
; Line 2
$LN3:
sub rsp, 56 ; 00000038H
; Line 3
mov rax, -3859904458173506500 ; ca6edd588f9f1c3cH
mov QWORD PTR x$[rsp], rax
; Line 5
mov rdx, QWORD PTR x$[rsp]
lea rcx, OFFSET FLAT:$SG695
call printf
; Line 6
xor eax, eax
add rsp, 56 ; 00000038H
ret 0
main ENDP
_TEXT ENDS
END
Note how that constant is never assigned, its address is never dereferenced. Because it does not have an address. It is loaded directly from the mapped executable image into the read-only code segment. The value cannot be modified because it is loaded directly into a register from the (immediate mode) value embedded in the instruction stream. It never exists in a data segment and so cannot be addressed.
So, for goodness sake stop trying to defend your indefensible assertion that there is no difference between a constant and a write-once variable.
A read-only variable is initialised, at runtime, either from another variable requiring that:
- the address of the original variable be loaded into a register;
- that address be dereferenced to load a register with the value;
- the address of the read-only (write-once) variable be loaded into a register;
- that address be dereferenced to move the value from the register to the variables location.
Or, it must be initialised, at runtime, from a constant.
I'm not going to bother stepping through that scenario, because it is blatenetly obvious--even to you I hope--that initialising a read-only variable with a constant, involves more runtime effort than using the constant directly.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
|