Malloc &初始化-宏

发布于 2024-09-06 04:48:56 字数 802 浏览 6 评论 0原文

是否可以重写以下代码,使其符合 ISO C 标准? 以下宏正在执行 malloc & init 指定类型和值。

当前代码适用于 gcc 编译器 (u这是一个 gcc 扩展),但它不是标准的。如果我使用 -pedantic,我会收到警告。

#ifdef __GNUC__

#define NM_CVPTR(type, value) \
    ({ \
        type * var = NULL; \
        var = nm_malloc(sizeof(*var)); \
        *var = value; \
        (const void*) var; \
    }) \

#define NM_VPTR(type, value) \
    ({ \
        type * var = NULL; \
        var = nm_malloc(sizeof(*var)); \
        *var = value; \
        (void*) var; \
    }) \

#define NM_PTR(type, value) \
    ({ \
        type * var = NULL; \
        var = nm_malloc(sizeof(*var)); \
        *var = value; \
        (type *) var; \
    }) \

#endif

Is it possible to rewrite the following code, so that it would be ISO C compliant ?
The following macros are doing a malloc & init for a given type and value.

The current code works with the gcc compilers (uses a gcc extension), but it's not standard. If I use -pedantic, I receive warnings.

#ifdef __GNUC__

#define NM_CVPTR(type, value) \
    ({ \
        type * var = NULL; \
        var = nm_malloc(sizeof(*var)); \
        *var = value; \
        (const void*) var; \
    }) \

#define NM_VPTR(type, value) \
    ({ \
        type * var = NULL; \
        var = nm_malloc(sizeof(*var)); \
        *var = value; \
        (void*) var; \
    }) \

#define NM_PTR(type, value) \
    ({ \
        type * var = NULL; \
        var = nm_malloc(sizeof(*var)); \
        *var = value; \
        (type *) var; \
    }) \

#endif

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我乃一代侩神 2024-09-13 04:48:56

这可以使用 逗号运算符 来完成,但在标准 C 中你将无法将变量声明为表达式的一部分,因此您必须将 var 的替换名称传递给宏:

// C - comma operator but not able to declare the storage during the
// expression.
#define NM_PTR(type, var, value) \
    (var = nm_malloc(sizeof(*var)), \
    *var = value, \
    (type * var))

This can be done using the comma operator, but in standard C you won't be able to declare a variable as part of an expression, so you will have to pass the name of var's replacement to the macro:

// C - comma operator but not able to declare the storage during the
// expression.
#define NM_PTR(type, var, value) \
    (var = nm_malloc(sizeof(*var)), \
    *var = value, \
    (type * var))
淡淡的优雅 2024-09-13 04:48:56

您可以使用memcpy分配一个值,然后返回指针。下面使用两个不同的版本,具体取决于您的初始值是否是原始类型(整数、浮点、指针...)或者是否是struct。值版本使用复合文字(type){ (value) },因此仅在C99中有效。

#include <stdlib.h>
#include <string.h>

static inline
void* memcpy_safe(void* target, void const* source, size_t n) {
  if (target) memcpy(target, source, n);
  return target;
}

#define NM_PTR_RVALUE(type, rvalue)                                     \
  ((type*)memcpy_safe(malloc(sizeof(type)), &(type){ (rvalue) }, sizeof(type)))

#define NM_PTR_LVALUE(type, lvalue)                                     \
  ((type*)memcpy_safe(malloc(sizeof(type)), &(lvalue), sizeof(type)))

typedef struct {
  int a;
} hoi;

hoi H7 = {.a = 7};

int main() {
  int* a = NM_PTR_RVALUE(int, 7);
  hoi* b = NM_PTR_LVALUE(hoi, H7);
}

(此处添加了使用内联函数的 NULL 检查,尽管最初并未要求这样做。)

顺便说一句,在 C++ 中,与 C 不同,赋值运算符 = 返回左值,因此对于 C++,您可能可以用它玩游戏。

You can use memcpy to assign a value and then have the pointer returned. The following uses two different versions depending on whether or not your initial value is a primitive type (integer,float, pointers...) or if it is a struct. The value version uses a compound literal (type){ (value) }, so it is only valid in C99.

#include <stdlib.h>
#include <string.h>

static inline
void* memcpy_safe(void* target, void const* source, size_t n) {
  if (target) memcpy(target, source, n);
  return target;
}

#define NM_PTR_RVALUE(type, rvalue)                                     \
  ((type*)memcpy_safe(malloc(sizeof(type)), &(type){ (rvalue) }, sizeof(type)))

#define NM_PTR_LVALUE(type, lvalue)                                     \
  ((type*)memcpy_safe(malloc(sizeof(type)), &(lvalue), sizeof(type)))

typedef struct {
  int a;
} hoi;

hoi H7 = {.a = 7};

int main() {
  int* a = NM_PTR_RVALUE(int, 7);
  hoi* b = NM_PTR_LVALUE(hoi, H7);
}

(Added a NULL check here that uses an inline function, although this wasn't requested originally.)

BTW, in C++ in contrast to C the assignment operator = returns an lvalue, so for C++ you could probably play games with that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文