James Franco
James Franco

Reputation: 4716

Undefined reference to function in case of a library

I am in the middle of porting code from Visual Studio to Mingw GCC. This component works fine in Visual studio however Mingw GCC complains about a undefined reference to a function. I have isolated the situation and am putting down the code here

File : Rng.h

#pragma once

#ifdef RNG_EXPORTS
#define RNG_API  __declspec(dllexport)
#else
#define RNG_API __declspec(dllimport)
#endif

RNG_API unsigned long GetRandom(unsigned long range);

File : Rng.cpp

#include "Rng.h"
#include "RngKiss.h"

static  TRngFile                    gRngFile;

unsigned long GetRandom(unsigned long range)
{
    gRngFile.generate_rnd();  //Linker Error : Undefined Reference to function.

    ....
}

File: RngKiss.h

#ifndef __RNGKISS_H__
#define __RNGKISS_H__

#ifndef ULONG
typedef unsigned long ULONG;
#endif  //ULONG


typedef struct
{
    ULONG   w, x, y, z;
} TRngRecord;


typedef struct
{
    TRngRecord  current, seed;
    ULONG   generate_rnd(void);
} TRngFile;

#endif  

File : RngKiss.cpp

#include "RngKiss.h"


ULONG   TRngFile::generate_rnd(void)
{
    ULONG d;
    return  d;
}

This is my output.

g++.exe -L..\..\..\mingw64\lib\boost -o bin\Debug\TestCodeBlocks.exe obj\Debug\main.o obj\Debug\Rng.o obj\Debug\RngKiss.o   
obj\Debug\Rng.o: In function `GetRandom(unsigned long)':
C:/Users/admin/TestCodeBlocks/Rng.cpp:8: undefined reference to `TRngFile::generate_rnd()'
collect2.exe: error: ld returned 1 exit status

Any suggestions on why I am getting this linker error and how i can resolve it ?

Upvotes: 1

Views: 1523

Answers (3)

Mike Kinghan
Mike Kinghan

Reputation: 61590

You have fallen foul of a bug (or at least an eccentricity) in your mingw64 compiler, in the rather obscure matter of compiling unnamed structs. I don't know what version you have, but my mingw32 4.8.1 has the same behaviour:

These typedefs in rngKiss.h:-

typedef struct
{
    ULONG   w, x, y, z;
} TRngRecord;


typedef struct
{
    TRngRecord  current, seed;
    ULONG   generate_rnd(void);
} TRngFile;

You may think that they respectively define a struct type called TRngRecord and another called TRngFile, but strictly they define TRngRecord and TRngFile to be aliases of struct types which themselves are unnamed.

The difference should be merely conceptual. So it is for Microsoft's compiler and for TDM GCC 4.9.2 on Windows, and so it is for GCC 4.9.2 and clang 3.5.1 on Linux.

Our mingw compilers, however, appear to hold that members of the unamed struct typedefed as TRngFile must have static linkage. Mine generates:

Dump of file rngKiss.o

File Type: COFF OBJECT

COFF SYMBOL TABLE
000 00000000 DEBUG  notype       Filename     | .file
    rngKiss.cpp
002 00000000 SECT1  notype ()    Static       | __ZN8TRngFile12generate_rndEv
...   

Hence the linkage error. Whereas TDM GCC 4.9.2 generates:

Dump of file rngKiss.o

File Type: COFF OBJECT

COFF SYMBOL TABLE
000 00000000 DEBUG  notype       Filename     | .file
    rngKiss.cpp
002 00000000 SECT1  notype ()    External     | _ZN8TRngFile12generate_rndEv
...

There are 3 solutions for this:

Change your compiler, say to TDM GCC.

Give names to your typedefed structs:

typedef struct TRngRecord
{
    ULONG   w, x, y, z;
} TRngRecord;


typedef struct TRngFile
{
    TRngRecord  current, seed;
    ULONG   generate_rnd(void);
} TRngFile;

or best of all:

Drop the typedefs, which are a strange and unnecessary way of naming classes in C++:

struct TRngRecord
{
    ULONG   w, x, y, z;
};

struct  TRngFile
{
    TRngRecord  current, seed;
    ULONG   generate_rnd(void);
}; 

....

#include "rngKiss.h"
...
static  TRngFile                    gRngFile;

Upvotes: 3

user3629249
user3629249

Reputation: 16540

the question states that the function is in a library.

this indicates the linker statement is missing either the '-Lpath to the library directory' and/or '-ltruncated libary name'

Upvotes: 0

user3629249
user3629249

Reputation: 16540

a few ideas come to mind.

1) the '::' scope operator is most often used to access a method of a class.  
   (another common use is to reference a function in a namespace)
   However, I do not see any class definition header file.
   (normally, the class header file is the same name as the class)

2) there has to be a prototype in a class header file 
   (usually this is part of the class declaration/interface) 
   for the generate_rnd() method.

So, where is the class header?

So, where is the method prototype?

Upvotes: 0

Related Questions