external relocation entries in non-writable section? (SOLVED)
Anders F Björklund
afb at algonet.se
Tue Jan 30 15:50:45 PST 2007
Rick Mann wrote:
>>Maybe it has something to do with that extra "const" ? What is that ?
>>(looks to me like it is trying to use the keyword like it was in C++)
>
> This is how the C header had it defined. In particular, CFStringRef is supposed to point to an immutable CFString, and (not defined here) CFMutableStringRef points to a mutable one (in the C header it drops the "const").
D doesn't have immutable references, it uses a Gentlemen's Agreement.
"if I hand you this reference, you promise not clobber it before .dup"
You can see this a lot with the D strings ("char[]"), for instance...
It's currently an unsolved issue with D, how to handle read-only args.
> I'm not sure how const works in D, although I know that you can't specify function parameters as const. I assume the "in" qualifier does the same thing, but I'm not sure (I've been able to write code that modifies unqualified parameters inside the function).
Basically it doesn't work as a modifier, only as a storage class...
So when porting C/C++ to D, all the "const" get silently dropped.
And the "in" qualifier is the default, so it doesn't add anything.
(there are enormous amounts of discussions on this topic, in d.D)
> Ideally, I'd get a compile-time error if I passed a CFStringRef as a parameter that expected a CFMutableStringRef.
The typedef should take care of that, I think ? ("typedef" vs "alias")
What you don't get is protection from messing about with the innards.
>>So I'm not sure what else your code is doing differently than mine ?
>
> I'm not either. I wrote a sample program defining everything in one file, and it worked fine. I also moved the defs to a separate file, and it still worked fine (with the "const" in there). I called CFShow() to output the value of the constructed CFStringRef, and it worked great. I can't figure out what's going on...hmm. I just went to reproduce the error, and now it seems to be working...?
>
> Ah! In the same file that defines __CFStringMakeConstantString, I define this (lexically before __CFStringMakeConstantString):
>
> CFStringRef
> CFSTR(char[] inString)
> {
> return __CFStringMakeConstantString(inString.ptr);
> }
>
> If I move it to after __CFStringMakeConstantString(), then it works okay.
Might be a GDC/Mac quirk. It does fail to create the $stub,
if you declare it as an extern(C) *after* you first use it.
The $stub is an assembly construct looking something like:
(in PowerPC assembler, just ignore this part if confusing)
.picsymbol_stub
L___CFStringMakeConstantString$stub:
.indirect_symbol ___CFStringMakeConstantString
mflr r0
bcl 20,31,L0$___CFStringMakeConstantString
L0$___CFStringMakeConstantString:
mflr r11
addis
r11,r11,ha16(L___CFStringMakeConstantString$lazy_ptr-L0$___CFStringMakeConstantString)
mtlr r0
lwz
r12,lo16(L___CFStringMakeConstantString$lazy_ptr-L0$___CFStringMakeConstantString)(r11)
mtctr r12
addi
r11,r11,lo16(L___CFStringMakeConstantString$lazy_ptr-L0$___CFStringMakeConstantString)
bctr
.data
.lazy_symbol_pointer
L___CFStringMakeConstantString$lazy_ptr:
.indirect_symbol ___CFStringMakeConstantString
.long dyld_stub_binding_helper
Basically it looks up the external symbol indirectly,
rather than just branching to the local symbol directly.
i.e. extern(C) after: branch to ___CFStringMakeConstantString
extern(C) before: branch to L___CFStringMakeConstantString$stub
That is what your first variant did, which caused the
"external relocation entry" - due to label not being known.
Moral of the story: declare your extern(C) before using. :-)
I'm not sure if it is supposed to work, declaring it afterwards.
Might do a small test case and report to David for validation ?
--anders
More information about the Digitalmars-d-learn
mailing list