【问题标题】:Initializer with side-effect具有副作用的初始化程序
【发布时间】:2019-12-18 11:46:22
【问题描述】:

C18 标准在6.7.9/2 声明:

任何初始化程序都不应尝试为未提供的对象提供值 包含在正在初始化的实体中。

目前还不清楚这意味着什么。有一个相关的话题:Incosistent gcc diagnostic for string initialization。我引用的子句用于解释以下初始化产生的错误:

//error: excess elements in array initializer char a[5]
char a[5] = {'h','e','l','l','o','\0'}; 

initializer-list 的长度超过了正在初始化的数组的大小。

但考虑more trivial example

int main(void){
    int a;
    int b = (a = 3);
}

这里的初始化器是(a = 3),它是一个assignment-expression。并且初始化程序将一个值分配给另一个应该导致违反约束的对象。

为什么不打印任何诊断信息?

【问题讨论】:

    标签: c initialization language-lawyer


    【解决方案1】:

    这不是“为a 提供值”。这是一个具有在a 中存储值的副作用的表达式。 “提供值”应该在初始化的上下文中理解;它不是用于作业的短语。

    标准中的语言试图达到的一个不那么琐碎的例子可能是:

    struct {
        char a[4];
        char b[4];
    } foo = { { 'h', 'e', 'l', 'l', 'o' } };
    

    而(我认为;如果我错了,请纠正我)以下将是有效的,尽管令人困惑,C:

    struct {
        char a[4];
        char b[4];
    } foo = { 'h', 'e', 'l', 'l', 'o' };
    

    【讨论】:

    • 是的,后者也有效。还有像{ { 'h', 'e', 'l', 'l' }, 'o' };这样丑陋的东西@
    • @AnttiHaapala 如果initializer-list 仅包含 1 个元素,您的示例利用了省略 {} 的能力,对吧?
    • 另一个更糟糕的例子是{ { 'h', 'e', 'l'}, 'l' , 'o' };
    • @AnttiHaapala 6.7.9/20: 仅考虑列表中足够的初始化器来考虑子聚合的元素或成员或包含的联合的第一个成员;剩下的任何初始化程序都将用于初始化当前子聚合或包含的联合所属的聚合的下一个元素或成员这是您使用的吗?
    • @St.Antario 那是 R. 的第二段摘录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多