当人们说C ++有“不可判断的语法”时,人们意味着什么?

当他们这样说时,人们的意思是什么? 对程序员和编译器有什么影响?


这与C ++的模板系统是图灵完整的事实有关。 这意味着(理论上)您可以在编译时使用可以使用任何其他Turing完整语言或系统的模板来计算任何东西。

这有一些副作用,一些明显有效的C ++程序无法编译; 编译器将永远无法确定程序是否有效。 如果编译器能够决定所有程序的有效性,它就能够解决停机问题。

请注意,这与C ++语法的歧义无关。


编辑:Josh Haberman在下面的评论和博客文章中指出了一个很好的例子,即为C ++构造一个分析树实际上是不可置信的。 由于语法的模糊性,语法分析与语义分析是不可分离的,而语义分析也是不可能的,语法分析也是如此。

另见(Josh的帖子链接):

  • C ++语法:类型名称与对象名称问题
  • C ++语法:类型vs对象和模板专业化

  • 它可能意味着C ++语法在语法上不明确,您可以根据上下文写下一些代表不同内容的代码。 (语法是对语言语法的描述,它决定了a + b是一个加法操作,涉及变量a和b。)

    例如, foo bar(int(x)); ,如书面所示,可以是一个变量的声明,称为bar,类型为foo,int(x)是一个初始化程序。 它也可以是一个名为bar的函数的声明,取一个int并返回一个foo。 这是在语言中定义的,但不是语法的一部分。

    编程语言的语法很重要。 首先,这是一种理解语言的方法,其次,它是编译的一部分,可以做得很快。 因此,与C ++具有明确语法的C ++编译器相比,C ++编译器更难编写并且使用速度较慢。 此外,尽管一个好的编译器会提供足够的线索,但是更容易制作某些类型的错误。


    如果“有些人”包括约西克林宁,那么根据他在这里写的内容...

    考虑这个例子:

    x * y(z);
    

    在两种不同的情况下:

    int main() {
        int x, y(int), z;
        x * y(z);
    }
    

    int main() {
        struct x { x(int) {} } *z;
        x * y(z);
    }
    

    ......他的意思是“你不能通过查看x * y(z)来判断它是表达式还是声明。” 在第一种情况下,它意味着“使用参数z调用函数y,然后用x和函数调用的返回值调用operator *(int,int),最后丢弃结果。” 在第二种情况下,它表示“y是指向结构x的指针,初始化为指向与z相同的(垃圾和定时炸弹)地址。”

    假设你有一套COBOLmania,并且添加了DECLARE语言。 然后第二个会变成

    int main() {
        DECLARE struct x { x(int) {} } *z;
        DECLARE x * y(z);
    }
    

    并且可判定性会出现。 请注意,可确定性不会导致指向垃圾的问题消失。

    链接地址: http://www.djcxy.com/p/74859.html

    上一篇: What do people mean when they say C++ has "undecidable grammar"?

    下一篇: c++