tags:

views:

412

answers:

11

hello, i am getting the compile error:

Error 7 error C2084: function 'Boolean IsPointInRect(...)' already has a body

on my inline function, which is declared like this in a cpp file:

inline Boolean IsPointInRect(...) 
{
...
}

i have exactly the same function in another cpp file. might this be causing the problem? how can i solve it?

A: 

Get rid of one of them? What did you expect?

Perhaps you should explain why you need two versions...

Platinum Azure
cause i didnt expect that inline functions are accessible everywhere in the code then.
clamp
Ah, in that case you want the "static" modifier, not inline.
Platinum Azure
Or "extern", if you just want to declare the function without redefining.
Platinum Azure
+5  A: 

putting them in appropriate namespaces makes simple solution. Even Anonymous will work.

the100rabh
Yes, that’s the C++ replacement of the old `static` solution. Why was this downvoted?
Konrad Rudolph
A: 

You can add "static" or "extern" in front of "inline" i think (I Know you can when using GCC), e.g:

static inline Boolean IsPointInRect(...) { ... }
S.C. Madsen
+2  A: 

If you move them both into a single header file that should solve it. Or declare one or both of them static. Or, if you are using MSVC, declare them __declspec(selectany).

John Knoeller
+1  A: 

Keep your inline functions in a header file, and use include guards to make sure the file isn't included twice.

snemarch
+11  A: 

As litb and AndreyT point out, this answer doesn't address the actual problem - see litbs answer for details.


While static, as Ofir said, gives you internal linkage, the "C++ way" is to use unnamed namespaces:

namespace
{
     inline Boolean IsPointInRect(/*...*/) { /*...*/ }
}

§7.3.1.1/1:

An unnamed-namespace-definition behaves as if it were replaced by

 namespace unique { /* empty body */ }
 using namespace unique; 
 namespace unique { namespace-body }

where all occurrences of unique in a translation unit are replaced by the same identifier and this identifier differs from all other identifiers in the entire program.

§7.3.1.1/2 adds:

The use of the static keyword is deprecated when declaring objects in a namespace scope (see annex D); the unnamed-namespace provides a superior alternative.

Georg Fritzsche
Err - What use does unnamed namespaces have here? They will equally fail here: `namespace { inline void a() { } } namespace { inline void a() { } }` (providing body twice!), and they will nothing provide in advance to "avoid" linker errors over inline functions (inline functions can already defined multiple times in a program - as long as in different translation units).
Johannes Schaub - litb
Indeed, tested it now in VC - thanks for the correction. So much for just going with guesses about the problem and reacting to other answers. I'll keep the answer for now for the reference to yours
Georg Fritzsche
Hm, why did my answer get accepted now? What was the problem now?
Georg Fritzsche
+2  A: 

As others have said, if you really want to limit the scope of the function to the cpp file then you should put it in a namespace, eg

namespace // anonymous
{
    inline bool IsPointInRect(...)
    {
        ...
    }
}

However it would seem like a maintenance issue to have the same function with the same body (ie they both do the same thing) in two different places - copy/paste style. If the two different functions have the same name but different bodies, then that too is a problem waiting to happen.

Obviously you have performance concerns (hence the inline), but it would really be best to only have the function written in one place! At a minimum put it in a header file (in an anonymous namespace) that is included where you need it. In reality you should do this 'cleanly' and then only revert to performance specific approaches when your profiler tells you to.

Cheers,

Michael
Michael
A: 

There are 2 ways of declaring inline functions:

  1. Inside the class: Any function defined inside the class is an inline function.

  2. Outside the class: If you define it outside the class then you need to use the keyword 'inline' along with the function signature.

If you have another function with the same name defined in a different class then it won't throw any exception as long as you are using the scope resolution operator(::) and dot(.) properly with the object name.

Maxood
+1  A: 

I have exactly the same function

Do you mean a function with the same name and type, or do you mean a function with the same name, type and body? There is nothing wrong with the latter, in fact that's what inline does - it lets you define the same function identically in different translation units. For the former you must ensure the function has file scope. inline does not give a function file scope, static and unnamed namespaces both do. An unnamed namespace is the preferred way of doing it in C++, at least according to the standard: static is deprecated.

Steve Jessop
A: 

1.use extern and static keyword

2.declare it inside a namespace

Foxcat
+4  A: 

You got some wrong answers in this thread. The problem in your code is that you define your inline function twice in your code:

inline Boolean IsPointInRect(...) { ... }   
inline Boolean IsPointInRect(...) { ... }

inline will, as someone else said correctly, already protect you from having an error risen by defining the function twice. You don't need static, nor will you need unnamed namespaces. Also notice that you shouldn't define inline functions that are supposed to be used by other translation units (a file where all #include and #if etc... are processed and expanded) within the .cpp file. Their definition have to be known by all translation units that use them - so put their definition only in the header file in that case - not in both the .cpp and the header file - that will yield to the error you get.

You also need header guards to avoid the above problem in each of your headers

// file foo.h
#ifndef POINTS_H_INCLUDED
#define POINTS_H_INCLUDED

inline Boolean IsPointInRect(...) { ... }

#endif


// file bar.cpp
#include "foo.h"
// does not include the content a second time anymore - the guards aboid it:
#include "foo.h" 

And you should make sure not to include a .cpp file into another .cpp file (.cpp files are not supposed to be included). You are supposed to include the header files into the .cpp files.

Johannes Schaub - litb