C auto 关键字用在哪里?
在大学时代,我读到过 auto 关键字,但随着时间的推移,我实际上忘记了它是什么。它定义为:
将局部变量定义为具有 本地生命周期
我从未发现它在任何地方使用,它是否真的使用过,如果是的话那么它在哪里使用以及在什么情况下使用?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
如果您阅读了IAQ(常见问题)列表,您会知道 auto 主要用于定义或声明车辆:
始终停在户外的车辆:
对于那些缺乏幽默感并想要“只是事实女士”的人:简短的答案是,永远没有任何理由使用完全
自动
。唯一允许您使用auto
的情况是对于已经具有auto
存储类的变量,因此您只需指定无论如何都会发生的事情。尝试对任何尚未具有auto
存储类的变量使用auto
将导致编译器拒绝您的代码。我想如果您想获得技术知识,您的实现不必是编译器(但它是),并且理论上它可以在发出诊断后继续编译代码(但它不会)。kaz 的小附录:
还有:
需要根据 ISO C 进行诊断。这是正确的,因为它声明车坏了。诊断是免费的,但关闭仪表板灯将花费您八十美元。 (如果您从 eBay 购买自己的用于车载诊断的 USB 加密狗,则为 20 个或更少)。
前面提到的
extern auto my_car
也需要诊断,因此,除了负责停车执法的城市工作人员之外,它永远不会通过编译器运行。如果您在任何代码库中看到大量
extern static auto ...
,那么您就处于一个糟糕的环境中;在整个地方都转向 Rust 之前,立即寻找更好的工作。If you'd read the IAQ (Infrequently Asked Questions) list, you'd know that auto is useful primarily to define or declare a vehicle:
A vehicle that's consistently parked outdoors:
For those who lack any sense of humor and want "just the facts Ma'am": the short answer is that there's never any reason to use
auto
at all. The only time you're allowed to useauto
is with a variable that already hasauto
storage class, so you're just specifying something that would happen anyway. Attempting to useauto
on any variable that doesn't have theauto
storage class already will result in the compiler rejecting your code. I suppose if you want to get technical, your implementation doesn't have to be a compiler (but it is) and it can theoretically continue to compile the code after issuing a diagnostic (but it won't).Small addendum by kaz:
There is also:
which requires a diagnostic according to ISO C. This is correct, because it declares that the car is broken down. The diagnostic is free of charge, but turning off the dashboard light will cost you eighty dollars. (Twenty or less, if you purchase your own USB dongle for on-board diagnostics from eBay).
The aforementioned
extern auto my_car
also requires a diagnostic, and for that reason it is never run through the compiler, other than by city staff tasked with parking enforcement.If you see a lot of
extern static auto ...
in any code base, you're in a bad neighborhood; look for a better job immediately, before the whole place turns to Rust.auto
是一个类似于static
的修饰符。它定义了变量的存储类别。但是,由于局部变量的默认值为auto
,因此您通常不需要手动指定它。本页列出了 C 中的不同存储类。
auto
is a modifier likestatic
. It defines the storage class of a variable. However, since the default for local variables isauto
, you don't normally need to manually specify it.This page lists different storage classes in C.
auto
关键字在 C 语言中没有用处。之所以存在,是因为在 C 语言之前就存在 B 语言,其中该关键字对于声明局部变量是必需的。 (B发展成了NB,又变成了C)。这是B 的参考手册。
正如您所看到的,该手册充满了使用
auto
的示例。之所以如此,是因为没有int
关键字。需要某种关键字来表示“这是变量的声明”,并且该关键字还指示它是本地变量还是外部变量(auto
与extrn
)。如果您不使用其中之一,就会出现语法错误。也就是说,x, y;
本身不是声明,但auto x, y;
是。由于随着语言的开发,用 B 编写的代码库必须移植到 NB 和 C,因此该语言的较新版本带有一些改进向后兼容性的包袱,从而减少了工作量。对于
auto
来说,程序员不必查找所有出现的auto
并将其删除。从手册中可以明显看出,现在 C 中已经过时的“隐式 int”(能够在前面不使用任何
int
的情况下编写main() { ... }
)也很糟糕来自 B。这是支持 B 代码的另一个向后兼容功能。函数没有在 B 中指定返回类型,因为没有类型。一切都是一个词,就像许多汇编语言一样。请注意如何将函数声明为
extrn putchar
,然后使其成为标识符使用的函数的唯一因素:它在像这样的函数调用表达式中使用putchar(x)
,这就是告诉编译器将该无类型字视为函数指针的原因。The
auto
keyword is useless in the C language. It is there because before the C language there existed a B language in which that keyword was necessary for declaring local variables. (B was developed into NB, which became C).Here is the reference manual for B.
As you can see, the manual is rife with examples in which
auto
is used. This is so because there is noint
keyword. Some kind of keyword is needed to say "this is a declaration of a variable", and that keyword also indicates whether it is a local or external (auto
versusextrn
). If you do not use one or the other, you have a syntax error. That is to say,x, y;
is not a declaration by itself, butauto x, y;
is.Since code bases written in B had to be ported to NB and to C as the language was developed, the newer versions of the language carried some baggage for improved backward compatibility that translated to less work. In the case of
auto
, the programmers did not have to hunt down every occurrence ofauto
and remove it.It's obvious from the manual that the now obsolescent "implicit int" cruft in C (being able to write
main() { ... }
without anyint
in front) also comes from B. That's another backward compatibility feature to support B code. Functions do not have a return type specified in B because there are no types. Everything is a word, like in many assembly languages.Note how a function can just be declared
extrn putchar
and then the only thing that makes it a function that identifier's use: it is used in a function call expression likeputchar(x)
, and that's what tells the compiler to treat that typeless word as a function pointer.在 C 中,auto 是一个关键字,表示变量是块的局部变量。由于这是块作用域变量的默认设置,因此它是不必要的并且很少使用(我认为我从未见过它在讨论关键字的文本中的示例之外使用)。如果有人能指出需要使用
auto
才能获得正确的解析或行为的情况,我很感兴趣。然而,在 C++11 标准中,
auto
关键字已被“劫持”以支持类型推断,其中变量的类型可以从其初始值设定项的类型中获取:正在添加类型推断主要是为了支持在模板中声明变量或从模板函数返回的变量,其中基于模板参数(或在实例化模板时由编译器推导)的类型通常手动声明会非常痛苦。
In C
auto
is a keyword that indicates a variable is local to a block. Since that's the default for block-scoped variables, it's unnecessary and very rarely used (I don't think I've ever seen it use outside of examples in texts that discuss the keyword). I'd be interested if someone could point out a case where the use ofauto
was required to get a correct parse or behavior.However, in the C++11 standard the
auto
keyword has been 'hijacked' to support type inference, where the type of a variable can be taken from the type of its initializer:Type inference is being added mainly to support declaring variables in templates or returned from template functions where types based on a template parameter (or deduced by the compiler when a template is instantiated) can often be quite painful to declare manually.
使用旧的 Aztec C 编译器,可以使用命令行开关将所有自动变量转换为静态变量(以提高寻址速度)。
但在这种情况下,使用
auto
显式声明的变量将保持原样。 (递归函数必须使用,否则将无法正常工作!)With the old Aztec C compiler, it was possible to turn all automatic variables to static variables (for increased addressing speed) using a command-line switch.
But variables explicitly declared with
auto
were left as-is in that case. (A must for recursive functions which would otherwise not work properly!)auto
关键字类似于 Python 中分号的包含,这是以前的语言所必需的 (B
),但开发人员意识到这是多余的,因为大多数事情都是auto
。我怀疑它是为了帮助从 B 到 C 的过渡而保留的。简而言之,一种用途是 B 语言兼容性。
例如 B 和 80 年代 C:
The
auto
keyword is similar to the inclusion of semicolons in Python, it was required by a previous language (B
) but developers realized it was redundant because most things wereauto
.I suspect it was left in to help with the transition from B to C. In short, one use is for B language compatibility.
For example in B and 80s C:
auto
只能用于块作用域变量。extern auto int
是垃圾,因为编译器无法确定它是否使用外部定义或是否使用 auto 定义覆盖 extern(而且 auto 和 extern 是完全不同的存储持续时间,例如static auto int
,这显然也是垃圾)。它总是可以选择以一种方式解释它,而是选择将其视为错误。auto
确实提供了一项功能,即在函数内启用“一切都是 int”规则。与函数外部不同,在函数外部,a=3
被解释为定义int a =3
,因为文件范围内不存在赋值,a=3< /code> 是函数内部的错误,因为显然编译器总是将其解释为对外部变量的赋值而不是定义(即使函数或中没有
extern int a
前向声明)文件范围),但像static
、const
、volatile
或auto
这样的说明符会暗示它是一个定义,编译器将其视为定义,但auto
没有其他说明符的副作用。因此,auto a=3
隐式为auto int a = 3
。诚然,signed a = 3
具有相同的效果,unsigned a = 3
始终是一个无符号 int。另请注意,“
auto
”对于是否将对象分配到寄存器没有影响(除非某些特定编译器注意到它,但这似乎不太可能)”auto
can only be used for block-scoped variables.extern auto int
is rubbish because the compiler can't determine whether this uses an external definition or whether to override the extern with an auto definition (also auto and extern are entirely different storage durations, likestatic auto int
, which is also rubbish obviously). It could always choose to interpret it one way but instead chooses to treat it as an error.There is one feature that
auto
does provide and that's enabling the 'everything is an int' rule inside a function. Unlike outside of a function, wherea=3
is interpreted as a definitionint a =3
because assignments don't exist at file scope,a=3
is an error inside a function because apparently the compiler always interprets it as an assignment to an external variable rather than a definition (even if there are noextern int a
forward declarations in the function or in the file scope), but a specifier likestatic
,const
,volatile
orauto
would imply that it is a definition and the compiler takes it as a definition, exceptauto
doesn't have the side effects of the other specifiers.auto a=3
is therefore implicitlyauto int a = 3
. Admittedly,signed a = 3
has the same effect andunsigned a = 3
is always an unsigned int.Also note '
auto
has no effect on whether an object will be allocated to a register (unless some particular compiler pays attention to it, but that seems unlikely)'Auto 关键字是一个存储类(决定变量和存储位置的生命周期的某种技术)示例。它具有这样的行为:该关键字的帮助创建的变量的生命周期(lifetime)仅驻留在花括号内
Auto keyword is a storage class (some sort of techniques that decides lifetime of variable and storage place) example. It has a behavior by which variable made by the Help of that keyword have lifespan (lifetime ) reside only within the curly braces
-std=iso9899:2024(你称之为C23)答案
对象定义的类型推断 — 作者:JeanHeyd Meneide — 项目编辑器以及C 和 C++ ISO/IEC 兼容性研究小组主席编程语言,C 工作组:
那些日子回答
专家 C 编程 — Peter van der Linden — 1994 年:
另请参阅 https://en.cppreference.com/w/c/keyword/auto< /a>.
新黑客词典,第三版。 — 埃里克·S·雷蒙德 — 1996 年:
-std=iso9899:2024 (you call it C23) answer
Type Inference for object definitions — by JeanHeyd Meneide — Project Editor and C and C++ Compatibility Study Group Chair at ISO/IEC Programming Languages, C working group:
Those days answer
Expert C Programming — by Peter van der Linden — 1994:
Also see https://en.cppreference.com/w/c/keyword/auto.
The New Hacker's Dictionary, 3rd ed. — by Eric S. Raymond — 1996:
我相信您熟悉 C 中的存储类说明符,它们是“extern”、“static”、“register”和“auto”。
“auto”的定义几乎在其他答案中给出,但这里是“auto”关键字的可能用法,我不确定,但我认为它依赖于编译器。
您会看到,关于存储类说明符,有一个规则。我们不能对一个变量使用多个存储类说明符。这就是为什么静态全局变量不能被外部化的原因。因此,只有他们的档案才知道他们。
当您进入编译器设置时,您可以启用优化标志以提高速度。编译器优化的方法之一是,它查找没有存储类说明符的变量,然后根据高速缓存的可用性和其他一些因素进行评估,以确定是否应该使用寄存器说明符来处理该变量。现在,如果我们想优化代码以提高速度,同时知道程序中的特定变量不是很重要并且我们不希望编译器将其视为寄存器,该怎么办?不过,通过输入 auto,编译器将无法将寄存器说明符添加到变量,因为输入“register auto int a;”或“自动注册 int a;”引发使用多个存储类说明符的错误。
综上所述,我认为auto可以通过优化来禁止编译器将变量视为寄存器。
这个理论不适用于 GCC 编译器,但我没有尝试过其他编译器。
I am sure you are familiar with storage class specifiers in C which are "extern", "static", "register" and "auto".
The definition of "auto" is pretty much given in other answers but here is a possible usage of "auto" keyword that I am not sure, but I think it is compiler dependent.
You see, with respect to storage class specifiers, there is a rule. We cannot use multiple storage class specifiers for a variable. That is why static global variables cannot be externed. Therefore, they are known only to their file.
When you go to your compiler setting, you can enable optimization flag for speed. one of the ways that compiler optimizes is, it looks for variables without storage class specifiers and then makes an assessment based on availability of cache memory and some other factors to see whether it should treat that variable using register specifier or not. Now, what if we want to optimize our code for speed while knowing that a specific variable in our program is not very important and we dont want compiler to even consider it as register. I though by putting auto, compiler will be unable to add register specifier to a variable since typing "register auto int a;" OR "auto register int a;" raises the error of using multiple storage class specifiers.
To sum it up, I thought auto can prohibit compiler from treating a variable as register through optimization.
This theory did not work for GCC compiler however I have not tried other compilers.