cstdint
typedef 肯定可以绑定到char变量.例如,它很可能uint_least8_t
与之结合unsigned char
并int_least8_t
结合signed char
.
标准是否保证类似的东西不会发生size_t
或类似的类型?或者至少有一个纯理论上的机会,这些类型将绑定到某些字符类型,unsigned char
甚至可能wchar_t
?
当我试图弄清楚下面代码发生了什么时,我得出了这个结论:
#include <iostream>
int main()
{
std::cout << (div) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
div
上述可以与被取代printf
,atoi
,difftime
等不论是否我#include
荷兰国际集团的适当的报头(ctime
,time.h
,cstdlib
,...,),我得到没有编译器错误和节目被打印1
.当我用函数名称作为前缀时,程序没有编译std::
.
Clang
警告解释了发生了什么:
warning: address of function 'div' will always evaluate to 'true' [-Wbool-conversion]
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
#include
d ,C库函数的名称也没有任何意义?std
?换句话说:如果我有这样分配的数组,它是否可以保证:
void *arr = calloc(nmemb, sizeof(some_type))
Run Code Online (Sandbox Code Playgroud)
然后elta
,eltb
,eltc
将所有指向在存储器中的相同位置,这将是类型的第二个元素some_type
此数组的?
some_type *elta = &((some_type*)arr)[1];
some_type *eltb = ((some_type*)arr)+1;
some_type *eltc = (char*)arr+sizeof(some_type);
Run Code Online (Sandbox Code Playgroud)
我问这个的原因是因为我试图在C中做一个"容器",如果这不成立,那么我就没有想法如何返回指向除第一个之外的任何其他元素的指针.
这样做肯定是有效的:
char src[] = "Allie has a cat.";
char buff[20];
strcpy(buff, src);
printf("%s\n", buff);
Run Code Online (Sandbox Code Playgroud)
或这个:
printf("Allie has a cat.\n");
Run Code Online (Sandbox Code Playgroud)
但是,缩短上述代码是否有效?
char buff[20];
strcpy(buff, "Allie has a cat.");
printf("%s\n", buff);
Run Code Online (Sandbox Code Playgroud)
或者写:
printf("%s", "Allie has a cat.");
Run Code Online (Sandbox Code Playgroud)
我问的原因是C字符串文字中的AFAIK与字符数组有些不同,虽然两个例子似乎都在起作用(ideone#1,ideone#2),但我认为当涉及到CI时不应该这样做任何我认为应该有效的东西,或者似乎只是对这种语言存在的陷阱数量的b/c工作,以及用这种语言编写一个看似无辜但仍然是UB的构造是多么容易.
假设我有一个这样的列表:
[('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
Run Code Online (Sandbox Code Playgroud)
我想将它转换为这样的列表:
[ [('Yadda', 5), ('Yadda', 9)], [('Blah', 12), ('Blah', 2), ('Blah', 4)] ]
Run Code Online (Sandbox Code Playgroud)
假设列表按照应该拆分的谓词进行排序 -
什么是Pythonic这样做的方式?
是否有任何功能可以做到这一点,还是我必须自己编写?
来自http://en.cppreference.com/w/c/memory/malloc:
必须使用free()或realloc()释放返回的指针.
来自http://en.cppreference.com/w/c/memory/calloc:
必须使用free()或realloc()释放返回的指针.
严格来说,为什么必须取消分配返回的指针?
现在我知道POSIX要求在程序终止时释放内存,所以在实践中malloc
立即调用和终止不会造成任何伤害.但这不是我要问的问题.
这个硬性要求("必须被解除分配")存在于C标准中,或者这是cppreference贡献者的发明,是为了敦促程序员不要泄漏内存?如果标准中存在这样的硬性要求,这是否意味着,根据C标准(POSIX和其他OS相关的事情除外!),如果返回的指针malloc
不是free
'd,或者是标准,则程序是UB 定义未能满足此要求的后果?(这会特别有趣,因为这可能意味着标准处理程序已经终止时会发生什么!)
为什么不alloca
检查它是否可以分配内存?
来自man 3 alloca
:
如果分配导致堆栈溢出,则程序行为未定义....如果无法扩展堆栈帧,则没有错误指示.
为什么alloca
不能/不能检查它是否可以分配更多内存?
我理解的方式是alloca
在堆栈上分配内存时在堆栈上(s)brk
分配内存.来自https://en.wikipedia.org/wiki/Data_segment#Heap:
堆区域由malloc,calloc,realloc和free管理,可以使用brk和sbrk系统调用来调整其大小
来自man 3 alloca
:
alloca()函数在调用者的堆栈帧中分配空间的大小字节.
并且堆栈和堆在收敛方向上增长,如此Wikipedia图中所示:
(上图来自Dougimed的Wikimedia Commons,发布于CC BY-SA 3.0)
现在,这两个alloca
并(s)brk
返回一个指向新分配内存的开始,这意味着它们必须知道哪里栈/堆结束当前时刻.的确,来自man 2 sbrk
:
以增量0调用sbrk()可用于查找程序中断的当前位置.
因此,他们理解它,检查是否alloca
可以分配所需的内存,实质上归结为检查堆栈的当前末端和堆的当前末尾之间是否有足够的空间.如果在堆栈上分配所需的内存会使堆栈到达堆,则分配失败; 否则,它会成功.
那么,为什么不能使用这样的代码来检查是否alloca
可以分配内存?
void *safe_alloca(size_t size)
{
if(alloca(0) - sbrk(0) < size) {
errno = ENOMEM;
return (void *)-1;
} else {
return alloca(size);
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说更加困惑,因为显然(s)brk
可以做这样的检查.来自man 2 …
与如何在Haskell中生产NaN相似...
在C中,有一个由INFINITY
定义的宏math.h
。
再次,在http://hackage.haskell.org/package/ClassyPrelude-0.1/docs/Prelude-Math.html中,我可以看到测试无罪的手段,但是却不愿意做。
因此,我唯一的选择是1/0
吗?
我的意思是,写这样的东西是否有效:
std::vector<int> vec(100, 0);
auto it = std::find(vec.end(), vec.end(), 5);
Run Code Online (Sandbox Code Playgroud)
为it
保证是vec.end()
或这是某种UB的?
如果允许这种结构,它将为我节省一些案例.
我对这段代码感到困惑:
| a b c| a := 1. b := [a := a + 1]. c := [a := a - 2. b].
10 timesRepeat: (a even ifTrue: b ifFalse: c). a
Run Code Online (Sandbox Code Playgroud)
我的假设是这段代码将设置a
为-19
。每次迭代将测试,如果a
是偶数,但a
会是奇数所以c
会被调用,从其减去2
从a
而不影响其校验。c
不会调用,b
因为如果我对块的理解正确,那么将返回块的最后一个元素,而不是求值;所以c
会返回b
,但timesRepeat
无论是无论如何返回丢弃所以这b
在c
没有任何效果。
我的假设被证明是错误的:这一段代码集a
来9
代替。为了查看发生了什么,我对这段代码进行了一些修改:
| a b c| a := 1. b := [Transcript show: (a displayString). a …
Run Code Online (Sandbox Code Playgroud)