我想用C创建一个结构,初始值如下:
typedef struct {
int id = 0;
char *name = "none";
} employee;
Run Code Online (Sandbox Code Playgroud)
我知道以上是不可能的,有没有其他方法可以做到这一点?
我正在寻找一段代码,可以告诉我结构中字段的偏移而不分配结构的实例.
IE:给定
struct mstct {
int myfield;
int myfield2;
};
Run Code Online (Sandbox Code Playgroud)
我可以写:
mstct thing;
printf("offset %lu\n", (unsigned long)(&thing.myfield2 - &thing));
Run Code Online (Sandbox Code Playgroud)
获得offset 4输出.如果没有mstct thing声明/分配一个怎么办呢?
我知道&<struct>并不总是指向结构的第一个字段的第一个字节,我可以在以后解释.
我们都知道解除引用空指针或指向未分配内存的指针会调用未定义的行为.
但是在传递给表达式时使用的规则是什么sizeof?
例如:
int *ptr = 0;
int size = sizeof(*ptr);
Run Code Online (Sandbox Code Playgroud)
这也未定义吗?
C标准明确规定有符号整数溢出具有未定义的行为。然而,大多数CPU都使用定义的语义为溢出实现签名算法(可能除法除法溢出为:x / 0和INT_MIN / -1)。
编译器的作家一直在走的优势undefinedness这种溢出的补充,往往会打破传统的代码非常微妙的方式更积极的优化。例如,此代码可能在较旧的编译器上有效,但在gccand的当前版本上不再有效clang:
/* Tncrement a by a value in 0..255, clamp a to positive integers.
The code relies on 32-bit wrap-around, but the C Standard makes
signed integer overflow undefined behavior, so sum_max can now
return values less than a. There are Standard compliant ways to
implement this, but legacy code is what it is... */
int sum_max(int a, unsigned char b) {
int …Run Code Online (Sandbox Code Playgroud) 我已经阅读过C++标准不允许的内容enum an_enum { a, b, c, };,而C的后期版本(我认为从90年代中期开始)确实允许使用尾随逗号进行此类声明.如果C++应该与C具有向后兼容性,那么为什么禁止使用此功能呢?任何特殊原因?
我还读到这样的尾随逗号实际上是好的,所以这只会增加混乱.
将来自外部源的两个字节数据转换为 16 位有符号整数的正确方法是使用如下辅助函数:
#include <stdint.h>
int16_t be16_to_cpu_signed(const uint8_t data[static 2]) {
uint32_t val = (((uint32_t)data[0]) << 8) |
(((uint32_t)data[1]) << 0);
return ((int32_t) val) - 0x10000u;
}
int16_t le16_to_cpu_signed(const uint8_t data[static 2]) {
uint32_t val = (((uint32_t)data[0]) << 0) |
(((uint32_t)data[1]) << 8);
return ((int32_t) val) - 0x10000u;
}
Run Code Online (Sandbox Code Playgroud)
上述哪个函数合适取决于数组是包含小端还是大端表示。字节序是不是问题的问题,在这里,我很奇怪,为什么zwol减去0x10000u从uint32_t值转换为int32_t。
为什么这是正确的方法?
转换为返回类型时如何避免实现定义的行为?
既然您可以假设 2 的补码表示,那么这个更简单的转换将如何失败: return (uint16_t)val;
这个幼稚的解决方案有什么问题:
int16_t le16_to_cpu_signed(const uint8_t data[static 2]) {
return …Run Code Online (Sandbox Code Playgroud) C 中的定义是否int a = 0, b = a++, c = a++;定义了行为?
或者几乎等价地,对象定义中的逗号是否像表达式中的逗号运算符一样引入序列点?
对于 C++ 也提出了类似的问题:
C++ 被广泛接受的答案是“是”,它在 C++11 标准第 8/3 段中有完整定义:
声明中的每个初始化声明符都会被单独分析,就像它本身在声明中一样
尽管本段仅涉及语法分析阶段,对于运行时的操作顺序还不够精确。
C语言的情况如何?C 标准是否定义了行为?
之前也有人问过类似的问题:
然而,答案似乎专门针对 C11 草案,并且可能不适用于 C 标准的最新版本,因为自 C11 草案以来,信息性附录 C 的措辞已发生变化,并且似乎也不与标准文本完全一致。
编辑:当然这样的初始化器似乎毫无用处地扭曲。我绝对不会容忍这样的编程风格和结构。这个问题源于关于一个琐碎定义的讨论:int res = 0, a = res;行为似乎没有完全定义(!)。具有副作用的初始化器并不少见,例如考虑以下一个:int arg1 = pop(), arg2 = pop();
我有一个简单的函数测试,如果两个数组彼此相反。它们似乎是相同的,只是tmp变量不同。一个有效,另一个无效。我一辈子都无法弄清楚为什么编译器会对此进行优化-如果确实存在优化问题(我的编译器是IAR Workbench v4.30.1)。这是我的代码:
// this works as expected
uint8 verifyInverseBuffer(uint8 *buf, uint8 *bufi, uint32 len)
{
uint8 tmp;
for (uint32 i = 0; i < len; i++)
{
tmp = ~bufi[i];
if (buf[i] != tmp)
{
return 0;
}
}
return 1;
}
// this does NOT work as expected (I only removed the tmp!)
uint8 verifyInverseBuffer(uint8 *buf, uint8 *bufi, uint32 len)
{
for (uint32 i = 0; i < len; i++)
{
if (buf[i] != (~bufi[i]))
{ …Run Code Online (Sandbox Code Playgroud) 在C中,为什么signed int速度比unsigned int?是的,我知道这个网站已被多次询问和回答(链接如下).但是,大多数人说没有区别.我编写了代码并意外地发现了显着的性能差异.
为什么我的代码的"未签名"版本比"签名"版本慢(即使在测试相同的数字时)?(我有一个x86-64英特尔处理器).
类似的链接
编译命令: gcc -Wall -Wextra -pedantic -O3 -Wl,-O3 -g0 -ggdb0 -s -fwhole-program -funroll-loops -pthread -pipe -ffunction-sections -fdata-sections -std=c11 -o ./test ./test.c && strip --strip-all --strip-unneeded --remove-section=.note --remove-section=.comment ./test
signed int 版注意:如果我明确声明signed int所有数字,则没有区别.
int isprime(int num) {
// Test if a signed int is prime
int i;
if (num % 2 == 0 || num % 3 == 0)
return 0;
else if (num % 5 == …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现malloc和freeC,我不知道如何重用内存.我目前struct看起来像这样:
typedef struct _mem_dictionary {
void *addr;
size_t size;
int freed;
} mem_dictionary;
Run Code Online (Sandbox Code Playgroud)
我malloc看起来像这样:
void *malloc(size_t size) {
void *return_ptr = sbrk(size);
if (dictionary == NULL)
dictionary = sbrk(1024 * sizeof(mem_dictionary));
dictionary[dictionary_ct].addr = return_ptr;
dictionary[dictionary_ct].size = size;
dictionary[dictionary_ct].freed = 1;
dictionary_ct++;
return return_ptr;
}
Run Code Online (Sandbox Code Playgroud)
当我释放内存时,我只会将地址标记为0(表示它是免费的).在我看来malloc,我会使用for循环来查找数组中的任何值0,然后将内存分配给该地址.我有点困惑如何实现这一点.