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