在 C 中定义 const 值

发布于 2024-07-09 09:47:35 字数 710 浏览 8 评论 0原文

我有一个 C 项目,其中所有代码都组织在 *.c/*.h 文件对中,我需要在一个文件中定义一个常量值,该值将是但也可以在其他文件中使用。 我应该如何声明和定义这个值?

它应该是 *.h 文件中的 static const ... 吗? 作为 *.h 文件中的 extern const ... 并在 *.c 文件中定义? 如果值不是原始数据类型(intdouble 等),而是 char *,那么这有什么关系?代码>结构? (虽然在我的例子中它是一个double。)

*.h文件中定义东西通常看起来不是一个好主意; 人们应该在 *.h 文件中声明事物,但在 *.c 文件中定义它们。 但是,extern const ... 方法似乎效率低下,因为编译器无法内联该值,而必须始终通过其地址来访问它。

我想这个问题的本质是:是否应该在 C 中的 *.h 文件中定义 static const ... 值,以便在多个地方使用它们?

I have a C project where all code is organized in *.c/*.h file pairs, and I need to define a constant value in one file, which will be however also be used in other files. How should I declare and define this value?

Should it be as static const ... in the *.h file? As extern const ... in the *.h file and defined in the *.c file? In what way does it matter if the value is not a primitive datatype (int, double, etc), but a char * or a struct? (Though in my case it is a double.)

Defining stuff inside *.h files doesn't seem like a good idea generally; one should declare things in the *.h file, but define them in the *.c file. However, the extern const ... approach seems inefficient, as the compiler wouldn't be able to inline the value, it instead having to be accessed via its address all the time.

I guess the essence of this question is: Should one define static const ... values in *.h files in C, in order to use them in more that one place?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

允世 2024-07-16 09:47:35

我遵循的规则是仅在 H 文件中声明事物并在 C 文件中定义它们。 您可以在单个 C 文件中声明和定义,假设它仅在该文件中使用。

通过声明,我的意思是通知编译器它的存在,但不为其分配空间。 这包括#define、typedef、extern int x 等。

定义为声明赋值并为其分配空间,例如int xconst int x。 这包括函数定义; 将这些包含在头文件中经常会导致代码空间的浪费。

我见过太多初级程序员在将 const int x = 7; 放入头文件中时感到困惑,然后想知道为什么会出现定义 x 的链接错误不止一次。 我认为至少,您需要 static const int x 以避免这个问题。

我不会太担心代码的速度。 计算机的主要问题(在速度和成本方面)很久以前就从执行速度转变为易于开发。

The rule I follow is to only declare things in H files and define them in C files. You can declare and define in a single C file, assuming it will only be used in that file.

By declaration, I mean notify the compiler of its existence but don't allocate space for it. This includes #define, typedef, extern int x, and so on.

Definitions assign values to declarations and allocate space for them, such as int x and const int x. This includes function definitions; including these in header files frequently lead to wasted code space.

I've seen too many junior programmers get confused when they put const int x = 7; in a header file and then wonder why they get a link error for x being defined more than once. I think at a bare minimum, you would need static const int x so as to avoid this problem.

I wouldn't be too worried about the speed of the code. The main issue with computers (in terms of speed and cost) long ago shifted from execution speed to ease of development.

擦肩而过的背影 2024-07-16 09:47:35

如果你需要常量(真实的、编译时常量),你可以通过三种方式做到这一点,将它们放入头文件中(这没有什么不好):

enum {
    FOO_SIZE = 1234,
    BAR_SIZE = 5678
};

#define FOO_SIZE 1234
#define BAR_SIZE 5678

static const int FOO_SIZE = 1234;
static const int BAR_SIZE = 5678;

在C++中,我倾向于使用枚举方式,因为它可以被限定为命名空间。 对于C,我使用宏。 不过,这基本上归结为品味问题。 如果您需要浮点常量,则不能再使用枚举。 在 C++ 中,我使用最后一种方法,即 static const double,在这种情况下(请注意,在 C++ 中 static 将是多余的;它们会自动变为静态,因为它们是 const)。 在 C 中,我会继续使用宏。

使用第三种方法会以任何方式减慢程序速度,这是一个神话。 我只是更喜欢枚举,因为你得到的值是右值 - 你无法获取它们的地址,我认为这是一个额外的安全性。 此外,编写的样板代码也少得多。 眼睛集中在常数上。

If you need constants (real, compile time constants) you can do that three ways, putting them into header files (there is nothing bad with that):

enum {
    FOO_SIZE = 1234,
    BAR_SIZE = 5678
};

#define FOO_SIZE 1234
#define BAR_SIZE 5678

static const int FOO_SIZE = 1234;
static const int BAR_SIZE = 5678;

In C++, i tend to use the enum way, since it can be scoped into a namespace. For C, i use the macro. This basicially comes down to a matter of taste though. If you need floating point constants, you can't use the enumeration anymore. In C++ i use the last way, the static const double, in that case (note in C++ static would be redundant then; they would become static automatically since they are const). In C, i would keep using the macros.

It's a myth that using the third method will slow down your program in any way. I just prefer the enumeration since the values you get are rvalues - you can't get their address, which i regard as an added safety. In addition, there is much less boiler-plate code written. The eye is concentrated on the constants.

往昔成烟 2024-07-16 09:47:35

您真的需要担心内联的优势吗? 除非您正在编写嵌入式代码,否则请坚持可读性。 如果它确实是一个神奇的数字,我会使用定义; 我认为 const 更适合 const 版本字符串和修改函数调用参数之类的事情。 也就是说,在 .c 中定义、在 .h 中声明的规则绝对是一个相当普遍接受的约定,我不会仅仅因为您可能保存内存查找而破坏它。

Do you really have a need to worry about the advantage of inline? Unless you're writing embedded code, stick to readability. If it's really a magic number of something, I'd use a define; I think const is better for things like const version strings and modifying function call arguments. That said, the define in .c, declare in .h rule is definitely a fairly universally accepted convention, and I wouldn't break it just because you might save a memory lookup.

国际总奸 2024-07-16 09:47:35

作为一般规则,您不要在标头中将事物定义为static。 如果您确实在标头中定义了static变量,则每个使用该标头的文件都会获得其声明的static内容的私有副本,这与DRY相反原则:不要重复

因此,您应该使用替代方案。 对于整数类型,使用 enum(在标头中定义)非常强大; 它也可以很好地与调试器配合使用(尽管更好的调试器也可以帮助处理#define宏值)。 对于非整数类型,标头中的 extern 声明(可选地使用 const 限定)和一个 C 文件中的单个定义通常是最好的方法。

As a general rule, you do not define things as static in a header. If you do define static variables in a header, each file that uses the header gets its own private copy of whatever is declared static, which is the antithesis of DRY principle: don't repeat yourself.

So, you should use an alternative. For integer types, using enum (defined in a header) is very powerful; it works well with debuggers too (though the better debuggers may be able to help with #define macro values too). For non-integer types, an extern declaration (optionally qualified with const) in the header and a single definition in one C file is usually the best way to go.

水染的天色ゝ 2024-07-16 09:47:35

我想了解您的问题的更多背景信息。 值的类型很重要,但您忽略了它。 C 中 const 关键字的含义非常微妙; 例如
常量字符*p;
并不意味着指针 p 是一个常量; 你可以随心所欲地写p。 你不能写的是 p 指向的内存,即使 p 的值发生变化,这一点也保持不变。 这是我唯一真正理解的案例; 一般来说,const 的微妙位置的含义使我难以理解。 但这种特殊情况对于函数参数非常有用,因为它从函数中提取了一个承诺,即参数指向的内存不会被改变。

每个人都应该知道另一种特殊情况:整数。 几乎总是,常量、命名整数应该在 .h 文件中定义为枚举文字。 枚举类型不仅允许您以自然的方式将相关常量分组在一起,而且还允许您在调试器中看到这些常量的名称,这是一个巨大的优势。

我已经写了数万行C语言; 如果我试图追踪它的话,可能有数百个。 (wc ~/src/c/*.c 表示 85,000 个,但其中一些是生成的,当然还有大量 C 代码潜伏在其他地方)。 除了这两种情况之外,我从未发现 const 有多大用处。 我很高兴学习一个新的、有用的例子。

I'd like to see more context for your question. The type of the value is critical, but you've left it out. The meaning of the const keyword in C is quite subtle; for example
const char *p;
does not mean that pointer p is a constant; you can write p all you like. What you cannot write is the memory that p points to, and this stays true even as p's value changes. This is about the only case I really understand; in general, the meaning of the subtle placement of const eludes me. But this special case is extremely useful for function parameters because it extracts a promise from the function that the memory the argument points to will not be mutated.

There is one other special case everyone should know: integers. Almost always, constant, named integers should be defined in a .h file as enumeration literals. enum types not only allow you to group related constants together in a natural way, but also allow you the names of those constants to be seen in the debugger, which is a huge advantage.

I've written tens of thousands of lines of C; probably hundreds if I try to track it down. (wc ~/src/c/*.c says 85 thousand, but some of that is generated, and of course there's a lot of C code lurking elsewhere). Aside from the two cases about, I've never found much use for const. I would be pleased to learn a new, useful example.

源来凯始玺欢你 2024-07-16 09:47:35

我可以给你一个间接的答案。 在 C++ 中(与 C 相对),const 意味着 static。 也就是说在C++中static constconst是一样的。 这告诉您 C++ 标准机构对这个问题的看法,即所有 const 都应该是静态的。

I can give you an indirect answer. In C++ (as opposed to C) const implies static. Thatis to say in C++ static const is the same thing as const. So that tells you how that C++ standards body feels about the issue i.e. all consts should be static.

莫相离 2024-07-16 09:47:35

对于 autoconf 环境:
您也可以随时在配置文件中定义常量。 AC_DEFINE() 我猜是在整个构建中定义的宏。

for autoconf environment:
You can always define constants in the configure file as well. AC_DEFINE() i guess is the macro to define across the entire build.

爱她像谁 2024-07-16 09:47:35

回答您问题的本质:
您通常不想想要在头文件中定义静态变量。
这将导致包含标头的每个翻译单元(C 文件)中存在重复的变量。

标头中的变量确实应该声明为 extern,因为这是隐含的可见性。
请参阅此问题以获得很好的解释。

实际上,情况可能没那么严重,因为编译器可能会将 const 类型转换为文字值。 但您可能不想依赖这种行为,尤其是在关闭优化的情况下。

To answer the essence of your question:
You generally do NOT want to define a static variable in a header file.
This would cause you to have duplicated variables in each translation units (C files) that include the header.

variables in a header should really be declared extern since that is the implied visibility.
See this question for a good explanation.

Actually, the situation might not be so dire, as the compiler would probably convert a const type to a literal value. But you might not want to rely on that behavior, especially if optimizations are turned off.

塔塔猫 2024-07-16 09:47:35

在 C++ 中,您应该始终使用

const int SOME_CONST = 17;

常量,并且

#define SOME_CONST 17

定义几乎总是会在稍后回来咬您。 常量在语言中,并且是强类型的,因此您不会因为一些隐藏的交互而得到奇怪的错误。 我会将 const 放入适当的头文件中。 只要是#pragma Once(或#ifndef x / #define x / #endif),您就不会遇到任何编译错误。

在 vanilla C 中,您可能会遇到必须使用#defines 的兼容性问题。

In C++, you should always use

const int SOME_CONST = 17;

for constants and never

#define SOME_CONST 17

Defines will almost always come back and bite you later. Consts are in the language, and are strongly typed, so you won't get weird errors because of some hidden interaction. I would put the const in the appropriate header file. As long as it's #pragma once (or #ifndef x / #define x / #endif), you won't ever get any compile errors.

In vanilla C, you might have compatibility problems where you must use #defines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文