我开始收到错误,“错误C2059:语法错误:'default argument'”表示一行代码,该代码行声明了一个带有字符串参数的函数,该函数被赋予了一个默认参数。这显然有点令人沮丧,因为错误消息并不完全具有启发性(我知道这是一个'默认参数'!),确切的声明在其他地方也可以。
稍微调整一下声明后,我发现它在包含类中的位置实际上有效。缩小它,我发现我通过在其默认参数之一后加一个分号来错误地声明一个不同的函数。编译器似乎很好,这看起来有点奇怪。我调查了一下,并提出了以下测试用例,试图找出正在发生的事情的本质:
enum TestEnum1
{
TEST_ONE
};
class TestClass
{
public:
enum TestEnum2
{
TEST_TWO,
TEST_THREE,
TEST_FOUR
};
void Func1( int iParm = TEST_ONE; ); // additional semicolon here
void Func2( std::string strParm = "" );
};
如上面的代码所示,Func2将产生我上面提到的编译错误。如果我将Func2移到Func1之上,那么一切都编译得很好。
如果我将Func1中的默认参数切换为显式数字或使用在TestClass中声明的枚举,那么我会得到该行的预期语法错误。
基本上,奇怪的是,如果我将默认参数的值设置为未在当前类中直接定义的枚举并且有点太分号 - 快乐,编译器将忽略语法错误,直到其他一些看似无关的事情最终导致解析器以一种非常难以理解的方式死亡。
我完全错过了什么吗?这是预期的行为吗?我当然犹豫不决地把它称为编译器中的错误,但这似乎不太正确。如果只是我误解了标准的某些内容,那么我想知道我错在哪里。
答案 0 :(得分:2)
我会说这不是编译器中的错误,因为编译器无法解析代码是以一种意想不到的方式表达的。
当编译器命中那个错误的分号时,它认为它知道一些不应该是真的代码。在它到达第二个函数的默认参数之前,编译器看不到任何与该信念相矛盾的东西,这显然不符合它认为代码在语法上的状态。它在那里调用错误,因为它是它看到问题的地方,但它并不能保证这就是代码问题实际存在的地方。
这是我经常看到的涉及错位或缺少花括号,圆括号或其他分隔括号的内容。编译器认为一切正常,直到它到达代码块的末尾并意识到左括号和右括号的数量不同,因此在那里调用错误。它实际上无法分辨丢失的括号应该去哪里。
因为此行为取决于所使用的确切解析过程,所以它依赖于编译器。但是,虽然这通常可以改变调用什么类型的错误,但在每个编译器中,它通常会出现某种错误。
答案 1 :(得分:1)
同意@tlayton。我自己在解析器中涉足了一点,我可以证明,为语法错误生成好的错误消息会使解析器的范围感混乱,这很难做到。
然而,这种特殊情况接近于缺陷。具有讽刺意味的是,在VS2010中,编译器仍会生成相同的糟糕错误消息,但IntelliSense解析器实际上会捕获它:
3 IntelliSense: expected a ')' c:\projects\cpptemp14\cpptemp14.cpp 20 36 cpptemp14
那是不可能的。您可以在connect.microsoft.com上报告。如果你不想花时间,请告诉我,我会报告(MVP职责)。