• Advertisement

Archived

This topic is now archived and is closed to further replies.

inline functions problem

This topic is 5830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone, When I try to make some functions inline using VC++ 6.0 - I get this error: Flock.obj : error LNK2001: unresolved external symbol "public: void __thiscall Boid::setCrashed(bool)" (?setCrashed@Boid@@QAEX_N@Z) Debug/prototype4.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe. The compiler doesnt mind when I make some functions inline but some it just wont allow. Why is this? I hope someone can help. Thanks, Tim.

Share this post


Link to post
Share on other sites
Advertisement
There are issues regarding external references and inline. Read the manual, read the C++ standard, search MSDN. Keep trying.

Share this post


Link to post
Share on other sites
Yes thats correct. Check the MSDN docs, but the general idea goes something like this:

If the function is inline, it really should be short. But anyway, an inline function for a class must be written in the same header as the class, INSIDE the class declaration:

class MyClass
{
public:
inline void DoSomething(void) { return; }
};

will work,
class MyClass
{
public:
inline void DoSomething(void);
};
inline void MyClass::DoSomething(void)
{
return;
}
will not work.

-----------------------------
The sad thing about artificial intelligence is that it lacks artifice and therefore intelligence.

Share this post


Link to post
Share on other sites
quote:
Original post by Promit
...INSIDE the class declaration

That''s the only part that isn''t true. It has to be in the same file as the declaration, and should be short. The compiler, however, is free to ignore your request to inline a function.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
The compiler, however, is free to ignore your request to inline a function.


Even with __forceinline?



Share this post


Link to post
Share on other sites
You have to link a specific library!

Go to the project configuration -> linker
and add the needed library


If the right library linked, it should compile well.

Or the linker cannot link your function, then i have no idea

Share this post


Link to post
Share on other sites
This simply just isnt true. VC++ will complain about inlining and you can force it to. In your implementation file (.cpp) make sure you use the extern keyword ex:

  

extern inline void Boid::setCrashed(bool b)
{........
}


now this will force VC++ to try to inline but its not garunteed it will, also this will cause the compiler to spit up a few warnings telling that the extern keyword is invalid for class definitions but dont worry, ive been using this in my project and it hasnt caused 1 error.

Share this post


Link to post
Share on other sites
quote:
Original post by Promit
Yes thats correct. Check the MSDN docs, but the general idea goes something like this:

If the function is inline, it really should be short. But anyway, an inline function for a class must be written in the same header as the class, INSIDE the class declaration:



Is this behaviour intended, i.e. actually part of the c++ standard? Or will it be sorted out in VC 7?

- seb

Share this post


Link to post
Share on other sites
So let me get it... if I split the class into .h (declaration) and .cpp (implementation), even if I use inline when I write the functions in the .cpp file, they still won''t be inlined (even if they are VERY short)?

Share this post


Link to post
Share on other sites
Not totally correct. I can have an inline function defined in a .CPP file that only the .CPP file uses, and that will be inlined correctly. For instance, if I have a private helper function that needs to access class variables, I can declare it private and inlined, define it in the .CPP file, and as long as my entire class is in that file everything''s fine.

We should really put up a tutorial on inline functions, there seems to be a lot of confusion about it. The main thing to get is that there is nothing magically different between .cpp and .h files; they''re really _all_ code files, and the .h files let you tack on common parts to your different .cpp files. If a function is inline, whoever uses it has to have the definition--NOT just the object code. If you understand all that, you should understand when & where to put your inline functions.

Share this post


Link to post
Share on other sites
Stoffel, I recently submitted an article covering this and related issues, which should be going up in a few weeks. Although it''s not 100% comprehensive and doesn''t quote from the standard every few paragraphs (as a truly accurate explanation would have to), it gives enough information to prevent people from having this problem.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

Share this post


Link to post
Share on other sites
Inline functions cannot be called from classes that are instantiated as pointers.

For example:

class TEST
{
void inline m_function(what ever);
}


main()
{
TEST* test;
test->m_function();
}

you will get the unresolved external symbol.
if you did this though you wont get that error.

main()
{
TEST test;
test.m_function();
}

Share this post


Link to post
Share on other sites
In words of more than one syllable, null_pointer, can you say why this is false?

Many thanks to everyone for these replies.

Tim.

Share this post


Link to post
Share on other sites
It''s false because it''s simply not the case - you can call inline functions from pointers to a class.

-Mezz

Share this post


Link to post
Share on other sites
    
#include <stdio.h>

class test
{
public:
void inline f(void) {printf("Hello\n");}
};

void main(void)
{
test *a = new test;
a->f();
}


Compiled and linked without any errors and warnings what so ever. And when executed, it outputs "hello", as expected. Compiled with MSVC 6 in release mode with language extensions disabled.

So yes, you can inline functions called from pointers.

Edited by - Brother Bob on February 5, 2002 9:35:44 AM

Share this post


Link to post
Share on other sites
Umm, about these inline functions, I think you''ll find that in VC6 that inlining is a function of the compiler and NOT the linker. What this means, in human terms, is that if the compiler cannot find the inline function''s definition then it can''t inline the function. Therefore if you include the inline function in the .h file rather than the .cpp file then the compiler can inline that function in any module which includes that .h file. If you define the inline function in a different module (i.e. in the cpp file) then the compiler can''t find the definition in that module and can''t inline it, the linker then goes nuts because the compiler says the function should have been inlined only it hasn''t ben.

Also __forceinline does NOT force the compiler to inline the function. When the compiler inlines functions it performs an analysis to determine whether or not the inline would be beneficial, since sometimes inlining can actually slow down code (apparently). __forceinline tells the compiler to ignore this analysis, nothing else. Inline functions can still be disbaled via the compiler settings (in VC6 go to the project settings dialog, then to the C/C++ tab, then the Optimizations category) and this disabling will affect __forceinline as well. Also some functions can NEVER be inlined:

1) Virtual functions, since the functions address is not resolved until run-time.
2) Functions which have variable length argument lists (though not ones which use default arguments)
3) Functions called via function pointers
4) Functions which return unwindable objects by value. I have to admit I''m not too sure what this means, it has something to do with the instruction stack...
5) Any function which uses exception handling of a different type to the function calling it.

Interestingly enough though certain rules which I was taught about inlining aren''t true in VC6, for example:

1) You can inline functions which contain loops.
2) You can also inline recursive functions, to do so use the following pragma in the modules you want the inlining to work:

#pragma(inline_recursion, on)

This will allow the compiler to inline the recursive function up to 8 times, you can change this value by using this pragma:

#pragma inline_depth( [0... 255] )

If you really want to know whether the compiler can inline a function then use ''__forceinline'' and, after making sure that inlining is enabled, try and compile the module. If the inlining fails the compiler will generate a level 1 warning with the value 4714

Share this post


Link to post
Share on other sites
From the above article:

quote:

One of the tensions in the C++ community is the pedagogical need to present a simple checklist set of rules versus the practical need to apply rules judiciously based on the situational context. The former is a response to the complexity of the language; the latter, to the complexity of the solutions we need to construct. The problem of when to declare virtual functions inline is a good illustration of this tension.



Wow, I thought _I_ sounded uppity.

It''s an interesting article, but I''d personally be afraid to do it. Maybe I''ll test it out here and there where appropriate, and of course be sure to check the disassembly. =)

Share this post


Link to post
Share on other sites

  • Advertisement