Tag: 语言律师

何时访问指向“死”对象的指针有效?

首先,为了澄清,我不是在引用无效指针的引用! 考虑以下两个例子。 例1 typedef struct { int *p; } T; T a = { malloc(sizeof(int) }; free(ap); // ap is now indeterminate? T b = a; // Access through a non-character type? 例2 void foo(int *p) {} int *p = malloc(sizeof(int)); free(p); // p is now indeterminate? foo(p); // Access through a non-character type? 题 […]

是std :: stoi实际上安全使用?

我和一个关于std::stoi的垮台的人进行了一次可爱的交谈。 说穿了,它内部使用std::strtol ,并抛出,如果报告错误。 据他们说,虽然std::strtol不应该为"abcxyz"input"abcxyz" ,导致stoi不会抛出std::invalid_argument 。 首先,这里有两个程序在GCC上testing了这些案例的行为: 与strtol Stoi旅馆 他们都在"123"上显示成功,在"abc"上显示失败。 我看了标准拉更多的信息: §21.5 Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if the converted value is outside the range of representable values for the return type. 这总结了依靠strtol的行为。 现在怎么样? 我在C11草稿中发现了这个: §7.22.1.4 If the subject sequence is empty or […]

编译器是否允许优化堆内存分配?

考虑以下使用new简单代码(我知道没有delete[] ,但它不涉及这个问题): int main() { int* mem = new int[100]; return 0; } 编译器是否允许优化new调用? 在我的研究中, g ++(5.2.0)和Visual Studio 2015没有优化new调用, 而铿锵(3.0+) 。 所有的testing都是在启用完全优化的情况下完成的(-O3代表g ++和clang,Visual Studio的发布模式)。 是不是new进行下的系统调用,使编译器不可能(和非法)优化呢? 编辑 :我现在已经从程序中排除了未定义的行为: #include <new> int main() { int* mem = new (std::nothrow) int[100]; return 0; } 铿锵3.0不会优化出来 ,但后来的版本 。 编辑2 : #include <new> int main() { int* mem = new […]

这个结构怎么能有sizeof == 0?

有一个旧post询问sizeof将返回0的构造。 有一些来自高信誉用户的高分回答说,由标准没有types或variables可以有0的大小,我同意100%。 然而,有这个新的答案提出了这个解决scheme: struct ZeroMemory { int *a[0]; }; 我正要对它进行倒票和评论,但是在这里度过的时间教会了我去检查我是否100%确定的事情。 所以…令我惊讶的是gcc和clang显示了相同的结果: sizeof(ZeroMemory) == 0 。 更多的是,一个variables的sizeof是0 : ZeroMemory z{}; static_assert(sizeof(z) == 0); // Awkward… Whaaaat …? Godbolt链接 这怎么可能?

C ++ switch语句expression式评估保证

关于交换机的标准说明如下。 “执行switch语句时,评估其条件并与每个case常量进行比较。 这是否意味着条件expression式只被一次性评估,并且由每个编译器的标准来保证呢? 例如,在switch语句头中使用某个函数时,会带来副作用。 int f() { … } switch (f()) { case …; case …; }

是int8_t和uint8_t打算是字符types?

鉴于这个C + + 11程序,我应该期望看到一个数字或字母? 还是不做预期? #include <cstdint> #include <iostream> int main() { int8_t i = 65; std::cout << i; } 标准是否指定此types是否可以是字符types?

重新定义C ++ 11中不允许的lambdas,为什么?

例: #include <functional> int main() { auto test = []{}; test = []{}; return 0; } 这会在gcc 4.7.2中发出以下错误消息: test.cpp: In function 'int main()': test.cpp:5:13: error: no match for 'operator=' in 'test = <lambda closure object>main()::<lambda()>{}' test.cpp:5:13: note: candidate is: test.cpp:4:16: note: main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&) <deleted> test.cpp:4:16: note: no known conversion for argument 1 from 'main()::<lambda()>' […]

a ] = 1是否会产生未定义的行为?

这个C99代码是否产生未定义的行为? #include <stdio.h> int main() { int a[3] = {0, 0, 0}; a[a[0]] = 1; printf("a[0] = %d\n", a[0]); return 0; } 在语句a[a[0]] = 1; , a[0]都被读取和修改。 我看了ISO / IEC 9899的n1124草案。它说(在6.5expression式中): 在前一个序列点和下一个序列点之间,一个对象应该通过评估一个expression式来最多修改其存储值一次。 此外,先前的值应该是只读的,以确定要存储的值。 它没有提到读取对象来确定要修改的对象本身。 因此这个陈述可能会产生未定义的行为。 不过,我觉得很奇怪。 这实际上是否会产生未定义的行为? (我也想知道在其他ISO C版本中的这个问题。)

构造函数的参考 – 创buildgenerics数组时没有警告

在Java中,不可能直接创build一个genericstypes的数组: Test<String>[] t1 = new Test<String>[10]; // Compile-time error 但是,我们可以使用原始types来执行此操作: Test<String>[] t2 = new Test[10]; // Compile warning "unchecked" 在Java 8中,也可以使用构造函数引用: interface ArrayCreator<T> { T create(int n); } ArrayCreator<Test<String>[]> ac = Test[]::new; // No warning Test<String>[] t3 = ac.create(10); 为什么编译器在最后一种情况下不显示警告? 它仍然使用原始types来创build数组,对吗?

为什么模板参数replace的顺序很重要?

C ++ 11 14.8.2 – 模板参数推导 – [temp.deduct] 7replace发生在函数types和模板参数声明中使用的所有types和expression式中。 expression式不仅包含常量expression式,例如出现在数组边界中的常量expression式或非types模板参数,还包括sizeof , decltype和其他允许非常量expression式的上下文中的常规expression式(即非常量expression式)。 C ++ 14 14.8.2 – 模板参数推导 – [temp.deduct] 7replace发生在函数types和模板参数声明中使用的所有types和expression式中。 expression式不仅包含常量expression式,例如出现在数组边界中的常量expression式或非types模板参数,还包括sizeof , decltype和其他允许非常量expression式的上下文中的常规expression式(即非常量expression式)。 replace按照词汇顺序进行,并在遇到导致扣除失败的条件时停止 。 添加的句子在处理C ++ 14中的模板参数时明确指出了replace的顺序。 替代的顺序是最经常不被重视的。 我还没有find一个关于为什么这个问题的文件。 也许这是因为C ++ 1y还没有完全标准化,但我认为这样的改变一定是出于某种原因而被引入的。 问题是: 为什么和什么时候,模板论证replace的顺序很重要?