自动在编译时如何将缩写与长期区分
How can auto distinguish short from long at compile time?
我很高兴能在我的C 程序中使用auto
变量。我知道使用auto
声明的变量使用模板规则推断变量类型,但是我对数字类型的工作方式感到困惑。假设我有:
auto foo = 12;
foo
的类型可以合理地为int
甚至unsigned char
。但是,假设在我的程序后面,我进行了一些数学,并为FOO分配了40亿个价值。那时,我希望foo
成为unsigned int
型或long
。
编译器如何预期在程序稍后将分配的值?
编译器与存在的信息一起使用,在您的情况下是整数文字12
。因此,它将foo
推论为int
类型。它没有任何预期。您可以使用适当的整数字面后缀:
auto foo = 12ul;
迫使foo
推导为unsigned long
。您不能将变量定义为类型int
,然后下线期望编译器以某种方式将其更改为另一种类型,仅仅是因为您分配了一个不适合先前使用类型的不同值。如果您这样做了,它将仅导致整数溢出,这是不确定的行为。
有关该主题的更多信息,请查看自动说明符和自动类型扣除参考。
; foo的类型可以合理地是int,甚至是未签名的char&quot&quot&quot
不,它不能。C 中的每个表达式都有一种类型,并且在语言中明确定义了。在您的情况下,表达式是整数字面的,因此类型与文字相对应。它是什么类型的,是由规则定义的:
字面的类型
整数字面的类型是该值可以拟合的第一种类型,从依赖于哪个数字碱和使用了哪个整数 - 苏联的类型列表中。
无后缀 - int,长int,长int(自C 11(
;编译器如何预期将在以后分配的值程序?&quot
不能。当您声明变量时确定类型,并且以后无法更改。
foo的类型可以合理地是int甚至未签名的char
它可以是很多事情,但实际上是只有一件事。
整数文字12
具有类型int
。
期。
,但是假设稍后在我的程序中,我进行了一些数学,并为FOO分配了40亿。那时,我希望FOO具有UNSIGNED INT或更长时间的类型。编译器如何预测程序后面将分配的值?
他们做不到,而他们却没有。foo
的类型不会改变。foo
没有类型的auto
(没有这样的东西(;它具有类型int
。从此以后,您的程序就像您写了int foo = 12;
一样。扣除/自动化结束。
那时,我希望
。foo
具有unsigned int
或long
。
这不是语言工作的方式。变量不能在运行时更改其类型。如果将变量定义为auto foo = 12;
,则意味着与int foo = 12;
完全相同的,无论未来的任何任务如何,因为12
的类型是int
。
编译器如何预测程序后来将分配的值?
他们不必。稍后分配的值将转换为变量的类型。如果该类型的值不超出该类型的范围,则确切的规则取决于您要处理的类型。
我的建议不是使用auto
的好地方。您知道哪些因素决定了您需要的类型,并且不能从直接上下文中推导。(但是,如果您可以将变量写为单个静态分配,那将永远不会发生。(
如果您知道该变量需要能够保持至少40亿个值,请将其声明为unsigned long
或long long int
。或者,如果您真的想防御不幸的选择这些类型的宽度(例如long
的平台为32位宽32位以支持旧版代码,但本机字样是64位(,请将其声明为uint_fast32_t
或int_fast64_t
。或者,如果您想要最小的,而不是最快的uint_least32_t
。(有时,最快的代码是使缓存中保持最多值的代码!(
如果您真正想要的是最快的签名或未签名类型,可以容纳40亿个,请说出您的意思!
就这些即时常数而言,我不会使用auto,而是该值来自另一个方法调用或从另一个变量分配。
如果您确实想要一种定义变量以匹配另一个变量的类型的方法,以便您可以与之互操作,但是您想分配一个常数值,然后使用sectType确保其大小兼容:
decltype(otherVar) myVar = 1234;
myVar += otherVar; // will work just as well as otherVar += myVar
在任何情况下,类型是由字面常数指定的,未装饰的12将定义一个int。
但是,您可以用u装饰常数,以使其无签名,或者l以使其长,甚至可以使其变得超长。不幸的是!
像所有其他答案一样,没有等效的迫使它短或字符。
但是还有其他一些方法可以预先指定所需类型。
auto foo = long(12);
std::cout << typeid(foo).name() << std::endl;
auto anotherFoo = long long (12);
//Some compilers may not allow multiple words like "long long"
//In that case you can use using keyword.
using llong = long long;
auto someOtherFoo = llong (12);
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- GCC对可能有效的代码抛出init list生存期警告
- 一位朋友将模板函数缩写为clang和gcc
- 在不复制临时对象的情况下延长其生存期
- 如何编写一个完美的缩写函数模板?
- 结束另一个线程中使用的对象的生存期
- "constinit"和"constexpr"之间的真正区别是什么?
- ((int) a) 和 (int(a)) 之间的区别是什么?
- "this"指针的值在对象的生存期内是否恒定?
- 创建具有全局生存期的 UObject
- C++17 和静态临时生存期的参考扩展
- 如何完全删除窗口的非工作区?
- 数组对象的生存期是否在重用其元素存储时结束?
- 返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?
- 共享指针生存期
- const auto & 和 auto & if reference 对象之间的区别是 const
- 具有空洞初始化的对象的生存期
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 指针引用的生存期(以 C++为单位)
- 为什么免费存储区中对象的生存期绑定到范围