| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 3 | |
Hi all I'm doing unit test with Qt. However, I always get 'undefined reference to function XXX' errors when compiling my test.cpp. I figured out the erros are due to the fact function XXX is inlined. So my question is what I am supposed to do to test inlined functions? Thanks Yifei
On Monday 17 March 2008 18:59:58 Yifei Li wrote: > Hi all > > I'm doing unit test with Qt. However, I always get 'undefined reference > to function XXX' errors when compiling my test.cpp. > > I figured out the erros are due to the fact function XXX is inlined. > > So my question is what I am supposed to do to test inlined functions? > undefined inlines? whut? mind posting some code? and maybe the full error message. -- [ signature omitted ]
Thank you for the reply. For example, here's I've been trying to do:
/////// file: a.h ///////////
class A
{
inline double foo();
};
///// file: a.cpp ////////
#include "a.h"
double A::foo()
{
double result;
...
return result;
}
/////file: test.cpp/////
#include <QtTest/QtTest>
#include "a.h"
class TestA
{
private slots:
void testfoo();
};
void TestA::testfoo()
{
A obj;
QCOMPARE(obj.foo(), expected_result);
}
-------------------------------------------
When I tried to compile test.cpp, I got :
test.cpp : undefined reference to 'TestA::foo()'
My pro file looks like:
CONFIG += qtestlib
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
HEADERS += a.h
SOURCES += a.cpp
----- Original Message -----
From: "Arvid Ephraim Picciani" <aep@xxxxxxxxxxxxxxx>
To: <qt-interest@xxxxxxxxxxxxx>
Sent: Monday, March 17, 2008 14:03
Subject: Re: a question on Qt unit test
> On Monday 17 March 2008 18:59:58 Yifei Li wrote:
>> Hi all
>>
>> I'm doing unit test with Qt. However, I always get 'undefined reference
>> to function XXX' errors when compiling my test.cpp.
>>
>> I figured out the erros are due to the fact function XXX is inlined.
>>
>> So my question is what I am supposed to do to test inlined functions?
>>
> undefined inlines? whut?
> mind posting some code? and maybe the full error message.
>
>
> --
> best regards/Mit freundlichen GrÃÃen
> Arvid Ephraim Picciani
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
--
[ signature omitted ]
On Monday 17 March 2008 20:07:28 Yifei Li wrote:
> Thank you for the reply. For example, here's I've been trying to do:
>
> /////// file: a.h ///////////
> class A
> {
> inline double foo();
> };
>
> ///// file: a.cpp ////////
> double A::foo()
> {
you can't put inlines in body files. thats.... pointless. didnt even expect it
to compile.
--
[ signature omitted ]
On Monday 17 March 2008 20:11:24 Arvid Ephraim Picciani wrote:
> On Monday 17 March 2008 20:07:28 Yifei Li wrote:
> > Thank you for the reply. For example, here's I've been trying to do:
> >
> > /////// file: a.h ///////////
> > class A
> > {
> > inline double foo();
> > };
> >
> > ///// file: a.cpp ////////
> > double A::foo()
> > {
>
> you can't put inlines in body files. thats.... pointless. didnt even expect
> it to compile.
Yes you can.
This is C++, not of of those odd languages that force you to use naming
conventions for files: you're free to do as you like.
If you wanted to you could call all your header files .cpp and all your
implementation files .h
It would be a bit messy, and there are probably very few people who will
appreciate it, but the compiler will not complain as long as you do it
correctly and keep including your .cpp files ;-)
The inline keyword is best viewer as a compiler hint. The compiler is free to
ignore is. You are also allowed to put an inline funtion in an implementation
file, and if you do that, it's a pretty good bet that the function will never
actually be inlined, but it will compile.
Also, you will need to link against the implementation file in that case (for
obvious reasons).
By the looks of it, the reason for the unresolved external is that the
original poster did not link to a.o . Test.cpp is not part of the project: so
qtestlib will build, but attempting to just build test.cpp requires linking
to a.o manually.
Happy coding,
Eric
--
[ signature omitted ]
On Monday 17 March 2008 23:09:11 Eric Methorst wrote: > Yes you can. > This is C++, not of of those odd languages that force you to use naming > conventions for files: you're free to do as you like. > If you wanted to you could call all your header files .cpp and all your > implementation files .h > It would be a bit messy, and there are probably very few people who will > appreciate it, but the compiler will not complain as long as you do it > correctly and keep including your .cpp files ;-) > > The inline keyword is best viewer as a compiler hint. The compiler is free > to ignore is. You are also allowed to put an inline funtion in an > implementation file, and if you do that, it's a pretty good bet that the > function will never actually be inlined, but it will compile. > Also, you will need to link against the implementation file in that case > (for obvious reasons). Yay. basic C++ lesson! where do i have to click to run my C++ script now? > By the looks of it, the reason for the unresolved external is that the > original poster did not link to a.o . Test.cpp is not part of the project: > so qtestlib will build, but attempting to just build test.cpp requires > linking to a.o manually. just bad that you are darn right. i just tested his code and it compiles. weird. I'd actually expect gcc to complain about not beeing able to inline at all. Propably it just ignores it anyway. *shrug*. gcc bugs coders way to less about useless code. -- [ signature omitted ]
Eric Methorst wrote: >By the looks of it, the reason for the unresolved external is that the >original poster did not link to a.o . Test.cpp is not part of the > project: so qtestlib will build, but attempting to just build test.cpp > requires linking to a.o manually. While that is a strong possibility, the compiler is free not to emit the function at all if it is marked inline. If it's not marked inline and it's declared in a separate header, the compiler will think twice about removing the function definition because it might be called from other .cpp files or even from another library entirely. In other words, the compiler cannot remove an out-of-line copy of a symbol with external linkage if it's not explicitly marked as inline. However, if it's marked as inline, the compiler may choose to completely inline it and remove the out-of-line definition. Other .cpp files and other libraries will get an unresolved symbol in that case. (The compiler may also ignore the inline keyword) This is not theory, it's actual scenario. I've seen this happen. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
On Tuesday 18 March 2008 00:48:03 Thiago Macieira wrote: > Eric Methorst wrote: > >By the looks of it, the reason for the unresolved external is that the > >original poster did not link to a.o . Test.cpp is not part of the > > project: so qtestlib will build, but attempting to just build test.cpp > > requires linking to a.o manually. > > While that is a strong possibility, the compiler is free not to emit the > function at all if it is marked inline. > > If it's not marked inline and it's declared in a separate header, the > compiler will think twice about removing the function definition because > it might be called from other .cpp files or even from another library > entirely. In other words, the compiler cannot remove an out-of-line copy > of a symbol with external linkage if it's not explicitly marked as > inline. > > However, if it's marked as inline, the compiler may choose to completely > inline it and remove the out-of-line definition. Other .cpp files and > other libraries will get an unresolved symbol in that case. (The compiler > may also ignore the inline keyword) Been there, done that, got the T-shirt ;-) > > This is not theory, it's actual scenario. I've seen this happen. -- [ signature omitted ]
Quoting Eric Methorst <arnalon@xxxxxxxxx>:
> On Monday 17 March 2008 20:11:24 Arvid Ephraim Picciani wrote:
> > On Monday 17 March 2008 20:07:28 Yifei Li wrote:
> > > Thank you for the reply. For example, here's I've been trying to do:
> > >
> > > /////// file: a.h ///////////
> > > class A
> > > {
> > > inline double foo();
> > > };
> > >
> > > ///// file: a.cpp ////////
> > > double A::foo()
> > > {
> >
> > you can't put inlines in body files. thats.... pointless. didnt even expect
> > it to compile.
> Yes you can.
> This is C++, not of of those odd languages that force you to use naming
> conventions for files: you're free to do as you like.
Sorry to burst your bubble, but you are flat out wrong.
The last sentence of para 3, chapter 3 "Basic concepts", section 2 "One
definition rule" of the C++ standard says
"An inline function shall be defined in every translation unit in which it is
used."
For debug builds, there's a good chance that defining a inline function once in
an implementation file will work, as many compilers do no inlining for debug
builds. It also might work for large functions that aren't inlined in optimized
builds as well. I'd also expect it to work if the functions are only called from
the implementation file, and not from any other translation unit. In any other
case, I would expect "unresolved external" errors at link time. And given the
rule above from the standard, the code is wrong and the link editor is right.
A+
Paul
--
[ signature omitted ]
On Tuesday 18 March 2008 16:02:51 Paul Floyd wrote:
> Quoting Eric Methorst <arnalon@xxxxxxxxx>:
> > On Monday 17 March 2008 20:11:24 Arvid Ephraim Picciani wrote:
> > > On Monday 17 March 2008 20:07:28 Yifei Li wrote:
> > > > Thank you for the reply. For example, here's I've been trying to do:
> > > >
> > > > /////// file: a.h ///////////
> > > > class A
> > > > {
> > > > inline double foo();
> > > > };
> > > >
> > > > ///// file: a.cpp ////////
> > > > double A::foo()
> > > > {
> > >
> > > you can't put inlines in body files. thats.... pointless. didnt even
> > > expect it to compile.
> >
> > Yes you can.
> > This is C++, not of of those odd languages that force you to use naming
> > conventions for files: you're free to do as you like.
>
> Sorry to burst your bubble, but you are flat out wrong.
Sorry to burst your bubble, but no I'm not.
>
> The last sentence of para 3, chapter 3 "Basic concepts", section 2 "One
> definition rule" of the C++ standard says
>
> "An inline function shall be defined in every translation unit in which it
> is used."
That is a misinterpretation of the specs on your part.
There's two ways of finding a function:
1) providing it compile time (classic inline function in a header file)
2) providing it at link time (regular functions)
If I define an inline function in a cpp file, it will compile for my class.
Any other class that wants to use this function must have it defined.
thus
"An inline function shall be defined in every translation unit in which it is
used."
is not an instruction to the compiler but to the *user* (=You the programmer)!
In other words, if I define my inline function in a.cpp then if I want to use
it in class b (b.cpp) I will need to:
---- file b.cpp ----
#include "b.h"
#include "a.cpp"
unless either b.cpp contains nothing else or only other inline functions (in
which case you'd better call it b_ext.h or something) this is never going to
compile because you will have multiple definitions for B's other (regular)
functions.
The rationale for this is quite simple: this is programming, not magic.
There is no way, that the compiler can ever possibly know what the definition
of your inline function is unless you include it. So treating that sentence
as an instruction to the compiler cannot be done because the compiler can
never know where the original definition *IS*.
Is the compiler supposed to go through every file in every directory in your
path and or include path and or -I <path>'s and look in every file present to
see if there's a definition for my inline B function? Should it scan all my
disks? connect to the internet? Google it???
Compiler output:
"unresolved external inline B::foo(). Should I yahoo it? (yes/no)"
Forgive the sarcasm, but he C++ spec is a little ambiguous.
My rule of thumb: it's a computer, not magic ;-)
At best, you might read this line as an instruction to the linker. But then,
there would be no difference between an inline function and a regular one
wouldn't there?
>
> For debug builds, there's a good chance that defining a inline function
> once in an implementation file will work, as many compilers do no inlining
> for debug builds. It also might work for large functions that aren't
> inlined in optimized builds as well. I'd also expect it to work if the
> functions are only called from the implementation file, and not from any
> other translation unit. In any other case, I would expect "unresolved
> external" errors at link time. And given the rule above from the standard,
> the code is wrong and the link editor is right.
>
> A+
> Paul
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Quoting Eric Methorst <arnalon@xxxxxxxxx>: > On Tuesday 18 March 2008 16:02:51 Paul Floyd wrote: > > Sorry to burst your bubble, but you are flat out wrong. > Sorry to burst your bubble, but no I'm not. You are still wrong. > > The last sentence of para 3, chapter 3 "Basic concepts", section 2 "One > > definition rule" of the C++ standard says > > > > "An inline function shall be defined in every translation unit in which it > > is used." > That is a misinterpretation of the specs on your part. No. You do understand what is meant by "translation unit", I hope. > There's two ways of finding a function: > 1) providing it compile time (classic inline function in a header file) > 2) providing it at link time (regular functions) There are more than that. > If I define an inline function in a cpp file, it will compile for my class. > Any other class that wants to use this function must have it defined. > thus > "An inline function shall be defined in every translation unit in which it is > used." > is not an instruction to the compiler but to the *user* (=You the > programmer)! Are you really claiming that the C++ standard does not provide instructions as to how compilers should behave? Specifically, that the ODR is only for programmers, not for compilers? > In other words, if I define my inline function in a.cpp then if I want to use > it in class b (b.cpp) I will need to: > ---- file b.cpp ---- > #include "b.h" > #include "a.cpp" > > unless either b.cpp contains nothing else or only other inline functions (in > which case you'd better call it b_ext.h or something) this is never going to > compile because you will have multiple definitions for B's other (regular) > functions. More precisely this will only work if a.cpp contains nothing with external linkage, assuming it is included more than once. What is your point? Conventionally, implementation files do not include other implementation files. Of course doing so is not illegal. Why not just do the simple, conventional thing and put your inlines with the declarations? That way experienced programmers will understand it, and the compiler and linker will compile and link it. [snip fatuous remarks] > At best, you might read this line as an instruction to the linker. But then, > there would be no difference between an inline function and a regular one > wouldn't there? It is clear to me that you do not understand the meaning of the inline keyword. There is always a difference between an inline function and a non-inline one. I suggest that you read the "Basic concepts" chapter of the C++ standard, and think about what the compiler does when it does not emit inline code for an inline function. And think a bit harder about your claim that "The inline keyword is best viewed as a compiler hint. The compiler is free to ignore it." A+ Paul -- [ signature omitted ]
/////// file: a.h ///////////
class A
{
inline double foo();
};
///// file: a.cpp ////////
#include "a.h"
double A::foo()
{
double result;
...
return result;
}
Above is your code. It should be changed to
/////// file: a.h ///////////
class A
{
double foo()
{
double result;
...
return result;
};
};
--
[ signature omitted ]
Yifei Li wrote:
>class A
>{
>inline double foo();
>};
What's the point of making it inline if you don't give the body of the
function?
Don't add "inline" unless you're also implementing the function.
--
[ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
On Monday 17 March 2008 18:59:58 Yifei Li wrote: > Hi all > > I'm doing unit test with Qt. However, I always get 'undefined reference > to function XXX' errors when compiling my test.cpp. > > I figured out the erros are due to the fact function XXX is inlined. > > So my question is what I am supposed to do to test inlined functions? Can you show a sample code? -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.