2

I don't think my question is a duplicate of this one.

what I try to do:

template<const char* szFunctionName>
class CReentranceLock
{
public:
    CReentranceLock(){}
    ~CReentranceLock(){}
    bool isLocked(){return s_bLock;}
    void setLocked(bool b)
    {
        const bool Result=(bool)InterlockedCompareExchange(
                    (unsigned long *)&s_bLock, b, !b);
    }

private:
    static bool s_bLock;
};

template<const char* szFunctionName>
bool CReentranceLock<const char*szFunctionName>::s_bLock=false; 
// error C2146: syntax error : missing ',' before identifier 'szFunctionName'

implying that all instances of CReentranceLock would have their own static, relying on the const char address of the function name passed as a parameter of the template.

and that could be used like this:

void CMyObject::InAnyFunction()
{
    const char* szFunctionName = __FUNCTION__; 
    CReentranceLock<szFunctionName> lock; // Edit: <- this doesn't work
    if(lock.isLocked()) return;
    lock.setLocked(true);
    /// business code
   lock.setLocked(false);
}

well that's only the theory... and unfortunately this doesn't compile under visual 2010, at the line where I try to initialize the statics.

error C2146: syntax error : missing ',' before identifier 'szFunctionName'

what am I doing or thinking wrong ?

PS: and I am not dealing with the fact that reentrance is smelling like an awful design (in MFC), I know, I am lost in the middle of it ;-)

Edit: though the answer below is good, and the definition compiles... my use in CMyObject::InAnyFunction() with a const char * as a template-parameter available at compile time seems to be wrong. :-(

Armut
  • 969
  • 8
  • 22
Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
  • The member `s_bLock` itself does not exist unless you instance a `CReentranceLock`. the `szFunctionName` is only a placeholder name that does not exist (as the compiler warns you). Try `const char Foo[] = {"Foo"}; bool CReentranceLock::s_bLock=false;` instead. (but you will set only the `s_bLock` of the `Foo` instance type of `CReentranceLock`). – PaperBirdMaster Jun 22 '12 at 09:14
  • @StephaneRolland : you're right, learned something. – Yochai Timmer Jun 22 '12 at 09:20
  • @StephaneRolland: Are you suggesting that `const char *` is convertible to an `int`? – dirkgently Jun 22 '12 at 09:24
  • @dirkgently well, that's what I intimately think, though it may depends whether you are on a 32 or 64 bits system. on a 64 bits system, I think it's a 64 bits integer. – Stephane Rolland Jun 22 '12 at 09:29
  • @Yochai, no pb man, you could have keep your comment. – Stephane Rolland Jun 22 '12 at 09:37

2 Answers2

3
bool CReentranceLock<const char*szFunctionName>::s_bLock=false; 

This should be:

bool CReentranceLock<szFunctionName>::s_bLock=false; 
Griwes
  • 8,805
  • 2
  • 43
  • 70
0

Just change the line to

bool CReentranceLock<szFunctionName>::s_bLock=false;

Raj
  • 114
  • 3