小编mad*_*phy的帖子

语义版本控制:主要还是较小的更改?

语义版本控制中,一般规则是仅在引入向后兼容功能时才增加次要编号,否则必须增加主要编号。将同样的方法,但使用不同的算法,是由使用的libtool

我有一个问题,关于什么被认为是向后兼容的更改,什么不可以。

假设我已经编写了一个库,并且该库的公共标头包含一个typedef名为的数据类型foo。在1.0.0版中,这typedef看起来像这样:

typedef struct foo_t {
    int x;
    int y;
} foo;
Run Code Online (Sandbox Code Playgroud)

然后,我决定更改数据类型,在下一个版本中,它将看起来像这样:

typedef struct foo_t {
    int x;
    int y;
    int z;
} foo;
Run Code Online (Sandbox Code Playgroud)

我仅在结构中添加了一个字段foo_t。这似乎是向后兼容的更改,但是上面的结构实际上是现在的另一种结构。我所做的并不是引入新功能,而其余所有功能都保持不变,而是我更改了已经存在的功能。

上面的数据类型通常用于与库的功能交换数据,但是用户可能已将其用于其他目的。如果用户使用1.0.0版编写了程序,而最后的更改构成了向后兼容的更改,则用户的程序也必须使用此新版本进行编译。

这个新版本如何命名为1.1.0或2.0.0?

编辑

您可以在此处阅读此讨论的进一步发展。

c struct semantic-versioning

5
推荐指数
1
解决办法
78
查看次数

使用uint64_t的不便

我有一个高度可移植的库(即使没有内核,它也可以在任何地方编译和运行良好),我希望它尽可能保持可移植性。到目前为止,我已经避免使用 64 位数据类型,但我现在可能需要使用它们 \xe2\x80\x93 准确地说,我需要一个 64 位位掩码。

\n

uint64_t我从来没有真正考虑过它,而且我也不是一个足够的硬件专家(特别是在嵌入式系统方面),但我现在想知道:使用(或等效地)有什么不便uint_least64_t?我可以想到两种方法来解决我的问题:

\n
    \n
  1. 实际可移植性:所有微控制器\xe2\x80\x93(包括8位CPU\xe2\x80\x93)都能够处理64位整数吗?
  2. \n
  3. 性能:与 32 位整数相比,8 位 CPU 对 64 位整数执行按位运算的速度有多慢?我正在设计的函数只有一个 64 位变量,但会对其执行大量按位操作(即在循环中)。
  4. \n
\n

c embedded performance portability uint64

5
推荐指数
1
解决办法
1769
查看次数

在具有多个“return”语句的可变参数函数中,是否需要在每个“return”语句之前调用“va_end()”?

有件事总是让我困惑va_end()。我经常读到这不是一个实际的函数,而是一个预处理器宏。尽管这听起来像是一个无关紧要的细节,但它实际上可能会影响va_end()需要调用的位置。

问题很简单:是否需要在具有多个语句的可变参数函数中的va_end()每个语句之前调用?returnreturn

NULL以下示例中的可变参数函数具有返回第一个非参数的简单任务。return正如你所看到的,函数体中有三个语句。其中之一出现在 之后va_start()但之前va_end()

这段代码正确吗?

#include <stdio.h>
#include <stdarg.h>

static const void * const FIRST_NON_NULL_END = (void *) "";

void * first_non_null (
    const void * const ptr1,
    ...
) {

    if (ptr1) {

        return ptr1 == FIRST_NON_NULL_END ? NULL : (void *) ptr1;

    }

    void * retval;
    va_list args;
    va_start(args, ptr1);

    do {

        retval = va_arg(args, void *);

        if (retval == FIRST_NON_NULL_END) {

            /* …
Run Code Online (Sandbox Code Playgroud)

c variadic-functions c-standard-library

5
推荐指数
1
解决办法
384
查看次数

何时使用互斥锁,何时不使用

我有一个名为my_list包含链接列表的全局变量(即,该变量是指向列表的第一个成员的指针)。该变量只能由两个线程(线程 A 和线程 B)编辑。如果列表变空,则该变量将设置为NULL。发生这种情况时,首先将变量设置为NULL,然后释放内存。

由于它是由两个线程编辑的,因此每次线程 A 或线程 B 接触该my_list变量时我都会使用互斥锁。到目前为止没有什么异常。

但是接下来出现了第三个线程,线程 C。该线程永远不会以任何方式接触链表,但它需要不时知道链表是​​否为空。所以,线程C唯一要做的就是

if (my_list) {

    do_something_completely_unrelated();

}
Run Code Online (Sandbox Code Playgroud)

我必须为此使用互斥体吗?我相信这是一个原子操作,因此不需要互斥体。它是否正确?

编辑

我将在这里添加一些背景信息。我想避免使用互斥体的原因是列表很少(总是)更新,但来自线程 C 的检查每隔几毫秒发生一次,因此操作越少越好。

如果列表显示为非NULL则线程 C 会触发使用互斥锁的正确检查,并且如果确认列表不为空,则线程 C 停止其强制检查。

c multithreading atomic thread-safety

4
推荐指数
1
解决办法
476
查看次数

switch case: case label does not reduce to an integer constant

I am perfectly aware of the mechanism behind the switch statement and why an integer constant is required. What I don't undestand is why the following case label is not considered an integer constant. What is it then? A non-existing variable? Can anyone categorize it? Does the C compiler really need to be so dumb?

struct my_struct {
    const int my_int;
};

switch (4) {

case ((struct my_struct) { 4 }).my_int:

    printf("Hey there!\n");
    break;

}
Run Code Online (Sandbox Code Playgroud)

And of course…

error: case …
Run Code Online (Sandbox Code Playgroud)

c switch-statement

3
推荐指数
1
解决办法
304
查看次数