Ç - 访问通过常量声明一个非const [英] C -- Accessing a non-const through const declaration

查看:109
本文介绍了Ç - 访问通过常量声明一个非const的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正在访问一个非 - 常量通过对象常量声明C标准允许的?
例如。为保证编译及以下code符合标准的平台上输出23和42?

Is accessing a non-const object through a const declaration allowed by the C standard? E.g. is the following code guaranteed to compile and output 23 and 42 on a standard-conforming platform?

翻译单元答:

int a = 23;
void foo(void) { a = 42; }    

翻译单元B:

#include <stdio.h>

extern volatile const int a;
void foo(void);

int main(void) {
    printf("%i\n", a);
    foo();
    printf("%i\n", a);
    return 0;
}

在ISO / IEC 9899:1999年,我刚刚发现(6.7.3条第5款):

In the ISO/IEC 9899:1999, I just found (6.7.3, paragraph 5):

如果试图修改与通过使用常量限定类型定义的对象
  与非const限定类型的左值的,其行为是不确定的。

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.

但在上述情况下,对象没有被定义为常量(只是声明)。

But in the case above, the object is not defined as const (but just declared).

更新

我终于找到了在ISO / IEC 9899:1999

I finally found it in ISO/IEC 9899:1999.

6.2.7,2

这指的是同一对象或函数应具有兼容类型的所有声明;
  否则,行为是不确定的。

All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.

6.7.3,9

有关两个限定类型是兼容的,两者应具有相同的合格
  兼容类型的版本; [...]

For two qualified types to be compatible, both shall have the identically qualified version of a compatible type; [...]

所以,它的未定义的行为。

So, it is undefined behaviour.

推荐答案

恩A包含的(只)定义一个。因此, A 真的是一个非const对象,它可以作为,例如在没有问题访问从功能。

TU A contains the (only) definition of a. So a really is a non-const object, and it can be accessed as such from a function in A with no problems.

我是pretty确保TU b都会调用不确定的行为,因为它的的声明中的不定义达成一致。到目前为止,我已经找到了支持,这是最好的UB报价6.7.5 / 2:

I'm pretty sure that TU B invokes undefined behavior, since its declaration of a doesn't agree with the definition. Best quote I've found so far to support that this is UB is 6.7.5/2:

每个声明符声明了一个鉴定网络连接器,并断言,当一个
  相同的形式的说明符的操作数出现在一个前pression,
  它指定一个函数或对象与范围,存储时间,
  并通过特定的声明科幻器类型所指示。

Each declarator declares one identifier, and asserts that when an operand of the same form as the declarator appears in an expression, it designates a function or object with the scope, storage duration, and type indicated by the declaration specifiers.

下面,B中的声明中称, A 的类型挥发性const int的。事实上,对象没有(合格)键入挥发性const int的,它具有(资质)键入 INT 。语义冲突是UB。

Here, the declaration in B asserts that a has type volatile const int. In fact the object does not have (qualified) type volatile const int, it has (qualified) type int. Violation of semantics is UB.

在实践中究竟会发生的是,涂某将被编译,如果 A 是非常量。 TU B将被编译为如果 A 是一个挥发性const int的,这意味着它不会缓存的价值 A 可言。因此,我希望它的工作中提供的接头没有注意到,反对不匹配的类型,因为我没有立即看到恩B如何可能可能发出code,它出了问题。然而,我的想象力的匮乏是不一样的担保行为。

In practice what will happen is that TU A will be compiled as if a is non-const. TU B will be compiled as if a were a volatile const int, which means it won't cache the value of a at all. Thus, I'd expect it to work provided the linker doesn't notice and object to the mismatched types, because I don't immediately see how TU B could possibly emit code that goes wrong. However, my lack of imagination is not the same as guaranteed behavior.

据我所知,没有什么标准说,挥发性在文件范围内的对象不能被保存在其他对象完全不同的存储库,提供了不同的指令阅读。实施仍然必须能够通过,也就是说,一个挥发性指针读取普通对象,所以假设为例子,正常的加载指令适用于特殊对象,它使用通过指针读取到的挥发性限定类型时。但是,如果(作为优化)发出执行特殊对象特殊指令和特殊指令的没有的工作,正常的对象,那么热潮。而且我认为这是程序员的错,虽然我承认,所以我不能完全确信它符合我只是发明了这个实施2分钟前。

AFAIK, there's nothing in the standard to say that volatile objects at file scope can't be stored in a completely different memory bank from other objects, that provides different instructions to read them. The implementation would still have to be capable of reading a normal object through, say, a volatile pointer, so suppose for example that the "normal" load instruction works on "special" objects, and it uses that when reading through a pointer to a volatile-qualified type. But if (as an optimization) the implementation emitted the special instruction for special objects, and the special instruction didn't work on normal objects, then boom. And I think that's the programmer's fault, although I confess I only invented this implementation 2 minutes ago so I can't be entirely confident that it conforms.

这篇关于Ç - 访问通过常量声明一个非const的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆