C:“const”关键字的行为
有人告诉我,如果我用 ANSI C 编码来按照变量的使用顺序进行声明,则断言指针不为空并且索引在范围内,并在使用变量之前进行初始化。
如果我声明一个 const
,我可以在断言和代码块之后初始化它吗?
在 Java 中,最终初始化必须在声明时进行,但是通过 ANSI C 实现,我可以初始化 const 一次,但不一定在声明时进行,这是否一致?
I've been told that if I'm coding in ANSI C to declare in the order that the variables will be used, assert that pointers are not null and that indices are within bounds, and to initialize just before usage of the variable.
If I declare a const
can I initialize it after a block of assertions and code?
In Java final initializations must occur at declaration, yet is it consistent through ANSI C implementations that I can initialize a const
once, but not necessarily at the time of declaration?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Java 编译器有少量的流程逻辑,允许您在声明后初始化
final
变量。这是合法的 Java:Java 将检测是否有任何分支未定义最终值。它不会分析条件,因此这不是合法的 Java,尽管逻辑上相似:
在 ANSI C89 中,
const
变量(extern
除外)必须在以下位置初始化:声明它们的语句。声明上的
extern
修饰符告诉编译器该变量是在不同的编译单元(或此编译单元中的其他位置)中初始化的。在 ANSI C99 中,您可以混合声明和代码,因此您可以在断言和代码块之后声明和初始化
const
变量。 1999 ANSI C 的可移植性仍然是一个问题。C89 的解决方法是注意代码前面的声明规则在块作用域而不是函数作用域起作用,因此您可以执行以下操作:
The Java compiler has a small amount of flow logic to allow you to initalise
final
variables after their declaration. This is legal Java:Java will detect if any branches leave the final value undefined. It won't analyse the conditions, so this is not legal Java, even though it's logically similar:
In ANSI C89,
const
variables ( other thanextern
) must be initialised in the statement they are declared in.The
extern
modifier on a declaration tells the compiler that the variable is initialised in a different complation unit ( or elsewhere in this compilation unit ).In ANSI C99, you can mix declarations and code, so you can declare and initialise a
const
variable after a block of assertions and code. Portability of 1999 ANSI C remains an issue.A work around for C89 is to note that the rules for declarations preceding code work at block scope rather than function scope, so you can do this:
请注意,即使在 C89 中,您通常也可以将定义移近首先通过引入一个裸块来使用,只是为了额外的范围。之前:
之后:
当然,使用 C99 时,您可以定义除开头之外的变量堵塞:
Be aware that even in C89, you can often move the definition closer to the point of first use by introducing a bare block just for the extra scope. Before:
After:
With C99 of course, you can define variables other than at the beginning of a block:
const
变量是只读的,必须在定义它们的地方进行初始化。此代码产生
错误:只读变量'foo'的分配
(GCC 4):const指针也是如此(此处注意:
const int *
不是a const 指针,而是指向 const 的指针):const
variables are read-only and must be initialised where they're defined.This code produces
error: assignment of read-only variable 'foo'
(GCC 4):The same goes for const pointers (note here:
const int *
is not a const pointer, but a pointer to const):缺少其他已显示的块作用域和 C99 声明方法,答案是否定的;你不能推迟 const 变量的初始化。无论如何,const 对于局部变量来说并不是很有用。我在 C 中使用 const 关键字的主要时间是:
有时,如果我认为局部变量可以帮助读者理解函数,我会将其声明为 const,但这种情况很少见。
Short of the block scope and C99 declaration methods other have shown, the answer is no; you cannot defer initialization of a const variable. Anyway, const is not very useful for local variables. The main times I use the const keyword in C are:
I sometimes declare local variables const if I think it will assist the reader in understanding a function, but that's pretty rare.
您无法在函数体内声明后初始化 const,但您可以在断言后打开一个块:
You can't initialize the const after declaration within the function body, but you can just open one block after your assertions:
如果您正在谈论将定义分成
两部分:
恐怕这在 C 中是不可能的。
如果我是您,我会尽力确保我理解您所描述的编码规则的意图。我怀疑理智的编码规则会阻止初始化变量(甚至非常量变量)。
回应各种评论:
不是 const 变量的声明。它是指向 const int 的非常量指针变量的声明。
您可以声明
,但在执行代码、断言检查等后仍然不能初始化 x。
If you are talking of splitting a definition
into two parts:
I'm afraid that's not possible in C.
If I were you, I would try to make sure I understand the intent of the coding rules that you describe. I doubt sane coding rules would prevent initializing variables (even non-const variables).
In response to various comments:
is not a declaration of a const variable. It is a declaration of a non-const pointer variable to a const int.
You can declare
but you can still not initialize x after having executed code, assertion checks, etc.
如果您想在 LHS 上放弃 const,请使用以下命令:
If you'd like to cast away const on the LHS, use this: