首页 > 其他分享 >宏定义导致数据异常问题

宏定义导致数据异常问题

时间:2024-01-15 17:58:53浏览次数:25  
标签:导致 gtc 定义 remove next queue prev 异常 define

/*
 * Copyright (C) gtc.
 */


#ifndef _GTC_QUEUE_H_INCLUDED_
#define _GTC_QUEUE_H_INCLUDED_

#include "gtc_core.h"


typedef struct gtc_queue_s  gtc_queue_t;

struct gtc_queue_s {
    gtc_queue_t  *prev;
    gtc_queue_t  *next;
};


#define gtc_queue_init(q)                                                     \
    (q)->prev = q;                                                            \
    (q)->next = q


#define gtc_queue_empty(h)                                                    \
    (h == (h)->prev)


#define gtc_queue_push(h, x)                                                  \
    (x)->next = (h)->next;                                                    \
    (x)->next->prev = x;                                                      \
    (x)->prev = h;                                                            \
    (h)->next = x


#define gtc_queue_tail(h)                                                     \
    (h)->prev


#define gtc_queue_remove(x)                                                   \
    (x)->next->prev = (x)->prev;                                              \
    (x)->prev->next = (x)->next


#define gtc_queue_pop(h)                                                      \
    gtc_queue_remove(h->prev)                                              


#define gtc_queue_data(q, type, link)                                         \
    (type *) ((u_char *) q - offsetof(type, link))


#endif /* _GTC_QUEUE_H_INCLUDED_ */

上述是一个队列的实现,这个队列实现是有问题的,问题在于 gtc_queue_pop 这个宏定义。
宏定义本质上是一种替换,gtc_queue_pop 中调用了 gtc_queue_remove ,这里的传参有讲究,
gtc_queue_remove 的入参是 h->prev,当执行 gtc_queue_remove 中 (x)->next->prev = (x)->prev; 语句时
会导致 h->prev 的指向发生了变化,导致下面的执行出现异常,宏不同于函数,它的简单替换可能会带来一些奇怪的问题
特此做好记录。

标签:导致,gtc,定义,remove,next,queue,prev,异常,define
From: https://www.cnblogs.com/zhanggaofeng/p/17965921

相关文章

  • 达梦数据库7_第 3 章 数据定义语句_3.6 管理表
    3.6管理表 3.6管理表3.6.1基表定义语句用户数据库建立后,就可以定义基表来保存用户数据的结构。达梦数据库中基表可以分为两类,分别为数据库表和外部表,数据库表由数据库管理系统自行组织管理,而外部表在数据库的外部组织,是操作系统文件。手册中如无明确说明基表均指数据库表......
  • 达梦数据库7_第 3 章 数据定义语句_3.5 管理 HTS 表空间
    3.5管理HTS表空间 创建HUGE表之前,必须要先创建一个HUGE表空间(HTS)。如果不创建,只能使用系统HUGE表空间HMAIN。3.5.1创建HTS表空间语法格式CREATEHUGETABLESPACE<表空间名>PATH<表空间路径>;参数1.<表空间名>表空间的名称,表空间名称最大长度128字节;2......
  • 达梦数据库7_第 3 章 数据定义语句_3.4 管理表空间
    3.4管理表空间3.4.1表空间定义语句创建表空间。语法格式CREATETABLESPACE<表空间名><数据文件子句>[<数据页缓冲池子句>][<存储加密子句>]<数据文件子句>::=DATAFILE<文件说明项>{,<文件说明项>}<文件说明项>::=<文件路径>[MIRROR<文件路径>]SIZE<文件大小>......
  • docker mysql8使用SSL及使用openssl生成自定义证书
    修改my.cnfvi/docker_data/mysql/conf/my.cnf[client]default-character-set=utf8mb4[mysql]default-character-set=utf8mb4[mysqld]character-set-server=utf8mb4default_authentication_plugin=mysql_native_password#增加sslssl保存,重启mysql容器dockerrestartmysql-8.0.23......
  • 自定义注解实现接口入参字段校验
    使用的类javax.validation导入的包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>xxxx.RELEASE</version></dependency>通过springb......
  • element-forge在Linux Centos中打包构建时遇到的异常问题解决方案
    环境:LinuxCentOS8x64electron:27.1.0electron-forge:7.1.0electrondev依赖包"devDependencies":{"@electron-forge/cli":"^7.1.0","@electron-forge/maker-deb":"^7.1.0","@electron-forge/maker-rpm&quo......
  • 自定义监控(kube-prometheus)
       ......
  • 定时任务及异步,自定义注解进行参数校验
    简单来说:浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。 如何在Spring/SpringBoot中优雅地做参数校验?springboot项目使用validation-api......
  • SpringBoot enter door基础_配springBoot项目,读取配置,配置全局异常捕获
    1、Spring是重量级企业开发框架 EnterpriseJavaBean(EJB) 的替代品,Spring为企业级Java开发提供了一种相对简单的方法,通过 依赖注入 和 面向切面编程 ,用简单的 Java对象(PlainOldJavaObject,POJO) 实现了EJB的功能虽然Spring的组件代码是轻量级的,但它的配置却是重......
  • 达梦数据库:DM变量的定义与赋值、字符串拼接
    1、变量的定义与赋值SqlServer格式declare@pintset@p=1;达梦数据库格式declarepint;p:=12、字符串拼接的符号连接操作符对两个运算数进行运算,其中每一个都是对属于同一字符集的字符串的求值。它以给定的顺序将字符串连接在一起,并返回一个字符......