View mode: basic / threaded / horizontal-split · Log in · Help
June 06, 2012
gdc and gcc object linking issues
This is a bit more related to C++ than D, it has to do with wrapping.
I've got 4 files:

test.h:
class Class
{
public:
   static int statField;
};

test.cpp:
#include "test.h"
extern "C" __attribute__((dllexport))
int getStatField()
{
   return Class::statField;
}

test.d:
extern(C) int getStatField();
class Class
{
   static int statField()
   {
       return getStatField();
   }
}

main.d:
import test;
void main()
{
   int x = Class.statField();
}

This is how I compile it (XP32):
g++ -m32 -g -I. -c test.cpp -o test_cpp.o
gdc -m32 -g -I. -c test.d -o test_d.o
gdc -m32 -g -I. -o main.exe test_cpp.o test_d.o main.d -lstdc++

But I get a linker error:
test_cpp.o: In function `getStatField':
D:\dev\code\d_code\testcpplink/test.cpp:5: undefined reference to
`Class::statField'
collect2: ld returned 1 exit status

If I change the static int field to a static function (and add
parenthesis for the function call) the linking works fine, e.g.:

test.h:
class Class
{
public:
   // was: static int statField;
   static int statField() { return 1; }
};

test.cpp:
#include "test.h"
extern "C" __attribute__((dllexport))
int getStatField()
{
   // was: return Class::statField;
   return Class::statField();
}

But for variables it doesn't link. What am I doing wrong?
June 06, 2012
Re: gdc and gcc object linking issues
On 06.06.2012 22:20, Andrej Mitrovic wrote:
> This is a bit more related to C++ than D, it has to do with wrapping.
> I've got 4 files:
>
> test.h:
> class Class
> {
> public:
>      static int statField;
> };
>

Old boring C++ :)

Once you have this definition due to moronic linkage model (and probably 
some other reasonable things) you have to have:

int Class:statField;

declared somewhere in you cpp files that you link together so that 
compiler knows where to put it (in terms of obj files).

> But for variables it doesn't link. What am I doing wrong?

Nothing, C++ is pile of dirt. :)

-- 
Dmitry Olshansky
June 06, 2012
Re: gdc and gcc object linking issues
On 06.06.2012 22:39, Dmitry Olshansky wrote:
> On 06.06.2012 22:20, Andrej Mitrovic wrote:
>> This is a bit more related to C++ than D, it has to do with wrapping.
>> I've got 4 files:
>>
>> test.h:
>> class Class
>> {
>> public:
>> static int statField;
>> };
>>
>
> Old boring C++ :)
>
> Once you have this definition due to moronic linkage model (and probably
> some other reasonable things) you have to have:
>
> int Class:statField;

int Class::statField; obviously



-- 
Dmitry Olshansky
June 06, 2012
Re: gdc and gcc object linking issues
On 6/6/12, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
>> Old boring C++ :)
>>
>> Once you have this definition due to moronic linkage model (and probably
>> some other reasonable things) you have to have:
>>
>> int Class:statField;
>
> int Class::statField; obviously

Thanks, that fixed it! :)

Yeah C++ is a weirdo.
June 07, 2012
Re: gdc and gcc object linking issues
A class declaration is simply a declaration, it doesn't allocate 
storage, so members end up being implicitly extern (or static 
inline for methods with bodies) except for instance fields, whose 
storage is allocated with the new operator. As static inlining a 
field has no sense, it becomes extern. You can declare extern 
variables in C too (try it). Extern declarations are included 
into each including module, but you can't do it with the 
variable's storage itself, so you should *define* the variable in 
a module where it will actually keep its value. If you define a 
variable in the header, it will be included in each including 
module and you'll get several instances of the variable and 
symbol collision at link time.

You can think of a class as an interface declaration which 
happens to expose some implementation details to you.
June 07, 2012
Re: gdc and gcc object linking issues
On 6/7/12, Kagamin <spam@here.lot> wrote:
> If you define a
> variable in the header, it will be included in each including
> module and you'll get several instances of the variable and
> symbol collision at link time.

This wasn't a collision error, it was a missing symbol error. The
variable is static, so it should be in the data or bss segment. You
seem to be talking about instance variables but that wasn't the issue
here.
June 07, 2012
Re: gdc and gcc object linking issues
On Thu, 07 Jun 2012 15:12:46 +0100, Andrej Mitrovic  
<andrej.mitrovich@gmail.com> wrote:

> On 6/7/12, Kagamin <spam@here.lot> wrote:
>> If you define a
>> variable in the header, it will be included in each including
>> module and you'll get several instances of the variable and
>> symbol collision at link time.
>
> This wasn't a collision error, it was a missing symbol error. The
> variable is static, so it should be in the data or bss segment. You
> seem to be talking about instance variables but that wasn't the issue
> here.

I don't think he was posting a solution to the OP, he was just describing  
some background :)

In the quoted passage above I suspect he was referring to a static/global  
variable defined in a C header, not a C++ class member static or otherwise.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
June 07, 2012
Re: gdc and gcc object linking issues
On Thursday, 7 June 2012 at 14:29:24 UTC, Regan Heath wrote:
> In the quoted passage above I suspect he was referring to a 
> static/global variable defined in a C header, not a C++ class 
> member static or otherwise.

I'm pretty sure you can define (with storage) global variable in 
header file both in C and C++. But don't qualify it static in C: 
this will make it hidden symbol so you will have several 
instances of the variable but no symbol collision.
June 07, 2012
Re: gdc and gcc object linking issues
On Thursday, 7 June 2012 at 14:12:56 UTC, Andrej Mitrovic wrote:
> This wasn't a collision error, it was a missing symbol error. 
> The
> variable is static, so it should be in the data or bss segment. 
> You
> seem to be talking about instance variables but that wasn't the 
> issue
> here.

You didn't define the variable. It doesn't matter in which 
section a variable is placed, but which module it's defined in. 
In D you have declarations in .di files, but .di files alone 
won't work as you won't have the declared variables' storage - 
you'll have to link to an object compiled from the corresponding 
.d file because .d has definitions and that's how actual D 
members *definitions* are compiled and their storage allocated in 
sections.
June 07, 2012
Re: gdc and gcc object linking issues
On 07.06.2012 23:04, Kagamin wrote:
> On Thursday, 7 June 2012 at 14:29:24 UTC, Regan Heath wrote:
>> In the quoted passage above I suspect he was referring to a
>> static/global variable defined in a C header, not a C++ class member
>> static or otherwise.
>
> I'm pretty sure you can define (with storage) global variable in header
> file both in C and C++.

Indeed you can. Kind of anti-pattern.

> But don't qualify it static in C: this will make
> it hidden symbol so you will have several instances of the variable but
> no symbol collision.

Some libraries actually count on something like this, but I can't 
remember offhand. Logging probably?

-- 
Dmitry Olshansky
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home