De functie Templated met twee typeparameters mislukt compileren wanneer gebruikt met een macro voor foutcontrole

Omdat iemand in onze groep uitzonderingen haat (laten we dat hier niet bespreken), gebruiken we meestal foutcontrolemacro's in onze C ++ -projecten. Ik ben een oneven compilatiefout tegengekomen bij het gebruik van een sjabloonfunctie met twee typeparameters. Er zijn een paar fouten (hieronder), maar ik denk dat de oorzaak een waarschuwing is:

warning C4002: too many actual parameters for macro 'BOOL_CHECK_BOOL_RETURN'

Waarschijnlijk het best uitgelegd in code:

#include "stdafx.h"


template
bool DoubleTemplated(B & value)
{
    return true;
}

template
bool SingleTemplated(A & value)
{
    return true;
}

bool NotTemplated(bool & value)
{
    return true;
}

#define BOOL_CHECK_BOOL_RETURN(expr) \
    do \
    { \
        bool __b = (expr); \
        if (!__b) \
        { \
            return false; \
        } \
    } while (false) \

bool call()
{
    bool thing = true;

//  BOOL_CHECK_BOOL_RETURN(DoubleTemplated(thing));
//  Above line doesn't compile.

    BOOL_CHECK_BOOL_RETURN((DoubleTemplated(thing)));
//  Above line compiles just fine.

    bool temp = DoubleTemplated(thing);
//  Above line compiles just fine.


    BOOL_CHECK_BOOL_RETURN(SingleTemplated(thing));
    BOOL_CHECK_BOOL_RETURN(NotTemplated(thing));

    return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
    call();
    return 0;
}

Dit zijn de fouten, wanneer de beledigende regel niet is becommentarieerd:

1>------ Build started: Project: test, Configuration: Debug Win32 ------
1>Compiling...
1>test.cpp
1>c:\junk\temp\test\test\test.cpp(38) : warning C4002: too many actual parameters for macro 'BOOL_CHECK_BOOL_RETURN'
1>c:\junk\temp\test\test\test.cpp(38) : error C2143: syntax error : missing ',' before ')'
1>c:\junk\temp\test\test\test.cpp(38) : error C2143: syntax error : missing ';' before '{'
1>c:\junk\temp\test\test\test.cpp(41) : error C2143: syntax error : missing ';' before '{'
1>c:\junk\temp\test\test\test.cpp(48) : error C2143: syntax error : missing ';' before '{'
1>c:\junk\temp\test\test\test.cpp(49) : error C2143: syntax error : missing ';' before '{'
1>c:\junk\temp\test\test\test.cpp(52) : error C2143: syntax error : missing ';' before '}'
1>c:\junk\temp\test\test\test.cpp(54) : error C2065: 'argv' : undeclared identifier
1>c:\junk\temp\test\test\test.cpp(54) : error C2059: syntax error : ']'
1>c:\junk\temp\test\test\test.cpp(55) : error C2143: syntax error : missing ';' before '{'
1>c:\junk\temp\test\test\test.cpp(58) : error C2143: syntax error : missing ';' before '}'
1>c:\junk\temp\test\test\test.cpp(60) : error C2143: syntax error : missing ';' before '}'
1>c:\junk\temp\test\test\test.cpp(60) : fatal error C1004: unexpected end-of-file found
1>Build log was saved at "file://c:\junk\temp\test\test\Debug\BuildLog.htm"
1>test - 12 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Om het even welke ideeën? Bedankt!

0
Is het een optie om die bepaalde persoon neer te schieten, of hem in ieder geval in te kaderen voor een affaire met de dochter van de baas?
toegevoegd de auteur Kerrek SB, de bron
@ KerrekSB - haha ​​:)
toegevoegd de auteur SirPentor, de bron

3 antwoord

De preprocessor heeft geen kennis van C ++ ! Het voert eenvoudigweg lexicale substituties uit.

Wanneer u een macro met meerdere argumenten declareert, worden de argumenten gescheiden door een komma. Omdat je een komma hebt in je macro-aanroep, roep je de macro aan met meerdere parameters, ondanks dat wordt verklaard dat er maar één argument is.

Haakjes worden door de PP begrepen als een tokengroep, dus alles binnen een reeks haakjes is één groot teken.

2
toegevoegd

Macro's zijn zich niet bewust van de taal en werken alleen met lexicale tokens. Een komma scheidt arguemnts voor een macro, dus de volgende code tracht de macro 'aan te roepen' met twee argumenten:

BOOL_CHECK_BOOL_RETURN(DoubleTemplated(thing));

DoubleTemplated and bool>(thing). That's the warning you are seeing, and cause of the other errors as well. The following is the correct way to protect against , in template arguments list:

BOOL_CHECK_BOOL_RETURN((DoubleTemplated(thing)));
1
toegevoegd

In de regel die niet compileert, wordt die komma geïnterpreteerd door de preprocessor als een scheidingsteken van de macroargumenten.

In de C99-standaard (ik heb de C ++ -norm niet bij de hand, maar deze zal erg op elkaar lijken), zien we het volgende in paragraaf 6.10.3:

De volgorde van voorbewerkingstokens begrensd door de buitenkant   bijpassende haakjes vormt de lijst met argumenten voor de functie-achtige   macro. De afzonderlijke argumenten in de lijst worden gescheiden door een komma   preprocessing tokens, maar komma preprocessing tokens tussen matching   innerlijke haakjes scheiden geen argumenten.

Dat is de reden waarom uw tweede macro-instantie werkt.

1
toegevoegd