标签: language-lawyer

如何理解[],(),复合文字运算符,.和 - >是后缀运算符?

在它自己的定义中,后缀运算符是在其所有操作数之后指定的运算符.

在C11标准中,后缀运算符定义为:

6.5.2邮政运营商

句法

post?x-expression:

    primary-expression
    post?x-expression [ expression ]
    post?x-expression ( argument-expression-listopt )
    post?x-expression . identi?er
    post?x-expression -> identi?er
    post?x-expression ++
    post?x-expression --
    ( type-name ) { initializer-list }
    ( type-name ) { initializer-list , }
Run Code Online (Sandbox Code Playgroud)
  1. 标准两个部分之前和之后的调用.,并->为操作数,这是我用粗体突出表现在以下报价.它是否意味着.并且->实际上是中缀运算符,尽管在标准中被称为后缀运算符?

    6.5.2.3结构和工会成员

    约束

    1 的第一个操作数 .运算符应具有原子,限定或不合格的结构或联合类型,第二个操作数应指定该类型的成员.

    2 - >运算符的第一个操作数应具有类型''指向原子,限定或不合格结构的指针''或''指向原子,合格或不合格的联合'的指针, 第二个操作数应指定一个成员.类型指向.

  2. 对于小节 [],()和复合文字不提字"操作数".所以

c expression operators language-lawyer

-6
推荐指数
1
解决办法
208
查看次数

为什么成员函数指针与C++中的普通函数指针不同?

在开始时,有C.
和C有结构,表达和功能来打包它们.这很好.
但是C也有goto和switch case掉线和随后使用的语法,所以可能不那么好.

它也有指针,从别名和指针算术中引起大量咬牙切齿!
但它也有函数指针,允许运行时调度,并随后欢喜.
现在,数据可以指示代码,以及指示数据的代码,并且都是头等(或接近).
对于任何可以指出的东西,可以用同一个指针指出:圣洁的空虚*.

它的荣耀都是平等的.

然后C++来了,并将数据和代码绑定到Object中.
而且,这只是语法糖,因为函数和方法没有那么不同,
(无论Sun或Oracle可能告诉你什么).

Obj-> Foo(int val)与Foo(Obj*this,int val)相同(大约),它们
在神圣的空隙*下仍然相等.

然后,继承,冲突,因为外部Derived类可能会添加到内部Base.
但是,在这些简单的时代,我们找到了一个解决方案:在Derived之前放入每个Base.
然后,使用相同的指针,我们可以指向孩子和父亲.

而且,任何可以指出的东西,都可以指向圣洁的空虚*.

随着虚拟,我们失去了我们的简单,并徘徊了很长时间.
想知道,如何处理钻石,或者不是椭圆形的圆圈.
但是,即使我们抛弃了C的旧租户,每个指令都简化为简单的asm,
我们也接受了,有些东西应该看起来很简单(即使它们很复杂).

因此,我们查看了出现并认为"足够好"的秘密VTables.
在我们引入隐藏数据的同时,我们降低了复杂性.
现在,通过虚拟机进行的任何呼叫都通过VTable重定向.
由于一个类的所有子对象都可以通过单个指针指向,这就足够了.

但即使调度方法发生了变化,我们仍然可以指出所有事情,圣洁无效*.

但后来有人提出,目前很多人都认为这是一个严重的错误:多重继承.
并且一个指针不再足够!两位基础父亲如何才能在一开始?
那么,VTable就不再足够了,因为我们怎么知道要指向哪个子对象!
而现在,钻石的问题比以前更糟糕,没有明显的解决方案,而我们之前的钻石需要现有的代码来应对未来的前景!

因此,必须在每次虚拟呼叫时进行指针调整.
因为Base类可能真的是伪装的MI Derived类,需要进行调整.
因此,对于使用MI的Choice Few的支持,我们都付出了代价.

突然之间,圣洁的空虚*再也无法储存那些简单的糖.
处理这种复杂性的原因是可怕的成员函数指针.

野兽需要它自己的语法,因为其他人都不够.
而且这种语法很少使用,它的优先级如此之低,以至于每次使用都需要parans.
虽然在神圣的标准中,邪恶的议会决定允许这些可怜的东西被投射,
但是当从类型转换为类型时,不调用而不调用行为最不明确!

然而,在语法和贪婪方面颓废,他们是胖子,无法适应无效*.
作为了解要指向的对象的唯一方法是进行调整,
深入嵌入指针,并使用每个VTable查找进行检查.

但兄弟们,这不是必须的.
这种实施的复杂性来自于一种最特殊的决策.

class Base1
{
public:
    virtual void foo();
};

class Base2
{
public:
    virtual void bar();
};

class Derived: public Base1, public Base2
{
public:
    void unrelated();
}
Run Code Online (Sandbox Code Playgroud)

如此处所示,在调用foo()或bar()时必须调整Derived*; 它不能同时指向Base1和Base2,就像简单单继承的情况一样.实际上,从基类调用时,确实无法正确预测需要多少偏移,这就是为什么大多数都有某种机制将其添加到vtable中.

然而: …

c++ oop member-function-pointers multiple-inheritance language-lawyer

-7
推荐指数
1
解决办法
352
查看次数

-8
推荐指数
1
解决办法
140
查看次数

if语句的这种用法是否会导致未定义的行为?

我想知道条件语句(例如if语句)的正确用法,以避免未定义的行为。让我们从一个例子开始:

uint8_t x = 0;
bool y = false;
bool z = false;

if ((x == 135) and !y and !z) {
    //do something
}
else if ((x == 135) and y) {
    x = 5;
    z = true;   
}
else if ((x == 5) and z) {
    x = 135;
    z = false;
}
else {
    //do something
}
Run Code Online (Sandbox Code Playgroud)

现在,是否通过不将所有3个变量都包含在每个条件中来获得不确定的行为?是否将所有未说明的条件都放入else语句中?如果是这样,如果我放弃else语句会怎样?我有完全相同的if语句(在更复杂的情况下),而且我似乎每次都不会进入正确的语句。

如果有此规定,请赐教。

c++ conditional if-statement undefined-behavior language-lawyer

-8
推荐指数
1
解决办法
121
查看次数

函数是否有可能返回与其显式返回值不同的值?

int my_func(void) {
    if(/*condition*/) {
        return 1;
    }
    else if (/*other condition*/) {
        return 2;
    }
    
    return 3;
}

int x = my_func();
Run Code Online (Sandbox Code Playgroud)

是否x保证始终是 3 个可能值之一?
以标准或 POSIX 或其他合法来源的引用形式提供证明。如果没有这样的来源,请提供逻辑证明(gcc/汇编)。

c language-lawyer

-10
推荐指数
2
解决办法
201
查看次数