每次#include(ed)时,标头的预处理方式都不同

时间:2014-10-31 17:17:54

标签: c macros header-files pic mplab

我有一个源文件,它提供队列结构的功能,并从数组中弹出/推送它们。

为简洁起见,以下是queue.c文件外观的示例 - 省略了一些不相关的定义。

queue.c

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "queue.h"

queue_t queueCreate ( void ) {
    queue_t newQueue;
    newQueue.state = QUEUE_EMPTY;
    newQueue.front = 0;
    newQueue.count = 0;
    return newQueue;
}

/*
 *  Returns the first in from the queue passed to it if possible
 */
enum STATE_QUEUE queuePop ( queue_t *queue, queueElement_t *pop ) {
    // if queue isn't empty
    if( !queue_isEmpty(queue) ) {
        // get element at front of queue
        (*pop) = (*queue).queue[(*queue).front];

        // decrease count by 1 as element has been removed from queue
        (*queue).count--;

        // if front needs to wrap round the array
        if( (*queue).front == ( QUEUE_SIZE - 1 )) {
            (*queue).front = 0;
        } else {
            (*queue).front++;
        }

        //
        queueState(queue);

        // return the popped element to the calling function
        return QUEUE_OK;
    }
    return QUEUE_EMPTY;
}

在头文件中,我声明了一些类型并使用宏来更改结构中的成员。使用此代码时,#define将指定这些结构中的成员。这些宏定义结构的内容永远不会被queue.c引用,但将在调用源文件中定义和使用

,这一点毫无价值。

标题看起来像这样

queue.h

#ifndef QUEUE_SIZE
    #define QUEUE_SIZE 10
    #define QUEUE_COUNT_TYPE BYTE
#else
    #ifndef QUEUE_COUNT_TYPE
        #if QUEUE_SIZE > 255
            #define QUEUE_COUNT_TYPE int
        #else
            #define QUEUE_COUNT_TYPE BYTE
        #endif
    #endif
#endif

    /* Queued types */
#ifndef QUEUE_TYPE
    #define QUEUE_TYPE  struct { \
                            int data; \
                        }
#endif

    /* Queue type definitions*/
    typedef QUEUE_TYPE queueElement_t;

    typedef struct {
        QUEUE_COUNT_TYPE front;
        QUEUE_COUNT_TYPE count;
        queueElement_t queue[QUEUE_SIZE];
    } queue_t;

    /* Function Prototypes */
    queue_t             queueCreate ( void );

调用源文件将重新定义QUEUE_TYPE以处理任何相关的结构。

我打算用#defines包装#include&#39;以便在我的项目中的多个源文件中使用此头文件时更改queueElement_t的定义。

我是否会遇到类型错误,因为函数名称相同,但处理不同的参数类型?或者有没有办法按照我的描述进行这项工作?

TL; DR如果我在整个项目中点缀的源文件中包含头文件,它使用宏来更改未在头文件中显式访问的结构成员,我是否会遇到任何错误

1 个答案:

答案 0 :(得分:1)

在您的特定情况下:是的。因为你有一个预期使用某种结构作为回报的函数。因此,当您尝试使用具有不同类型定义的两个不同模块的结构时,您将发现与您正在使用的平台上的ABI相关的非常有趣的问题。

但是,您可以切换到仅使用宏,这将更像C ++中的模板。小例子:

#define QUEUE_TYPE(element, size) struct { int front, count; type queue[size]; } 
#define QUEUE_INIT(queue) queue.front = queue.count = 0;
#define QUEUE_SIZE(queue) sizeof(queue.queue)/sizeof(queue.queue[0])
#define QUEUE_PUSH(queue,val) \
    if (queue.front < QUEUE_SIZE(queue)) queue.queue[queue.front++] = val;
...

struct {
   QUEUE_TYPE(int,10) member;
} my_var;
...
QUEUE_INIT(my_var.member);
QUEUE_PUSH(my_var.member, 10)