2015-07-10 29 views
4

我有我使用在我的嵌入的C程序的簡單FIFO環形緩衝器隊列(使用TI的C28x C/C++編譯器,其非常類似於GCC爲C89沒有擴展)。 數據被中斷隊列推入並彈出,所以隊列需要變化。不透明指針到易失性結構

我,通過聲明使得隊列用戶的隊列是否爲易揮發或不(我想在幾個項目具有不同的用途使用本)選擇使用揮發性執行隊列代碼本身沒有在使用中處理一個易失性隊列對象,而不是在實現中將隊列對象本身定義爲volatile。

在que.c

即:

struct QUE_Obj { /* Object & members are not defined as volatile. */ 
    void * data; 
    uint16_t capacity; 
    uint16_t head; 
    uint16_t tail; 
    uint16_t size; 
    bool full; 
    bool empty; 
} 

/* Implementation uses all non-volatile types. */ 
QUE_Handle QUE_init(void * data, uint_least8_t size, uint16_t capacity) { 
    /* ... */ 
    QUE_Handle q = (QUE_Handle)malloc(sizeof(struct QUE_Obj)); 
    /* ... */ 
    return q; 
} 

/* ... */ 

在queue.h:

typedef QUE_Obj * QUE_Handle; 
QUE_Handle QUE_init(void * data, uint_least8_t size, uint16_t capacity) 

main.c中:

/* Data buffer and queue handle declared to be for volatile data. */ 
static volatile uint16_t buffer[BUFFER_LENGTH] = {0}; 
volatile QUE_Handle que = QUE_init((void *)buffer); /* Buffer passed without volatile. */ 

我的問題然後,在最後一行在C中,當我將緩衝區投入到void *時,這是否會消除波動的任何有用性?

我應該代替定義QUE_Obj的成員始終動盪,調整中實現中使用揮發無論隊列的使用的類型?

問另一種方式,push()pop()功能是從中斷服務例程中調用的,但是它們的實現並不知道波動性,它們是否會被優化掉?

+4

*如果嘗試 通過使用帶非易失性限定類型的左值 來引用通過volatile限定類型定義的對象,則該行爲是未定義的。*您應該聲明指針具有揮發性。只是在說。 – this

+0

@這很好,謝謝你的標準報價! – Toby

回答

5

您不應該通過非易失性指針訪問易失性數據。考慮下面這個簡單的例子:

volatile int volatileVar; 
int* nonVolatilePtr = &volatileVar; 

每當你的代碼訪問volatileVar通過nonVolatilePtr編譯知道你正在訪問的數據是不穩定的,可能去優化訪問它(這顯然是一個意外的行爲)。我看到非易失性指針用於非易失性數據的用處很少。

如果你希望你的隊列通過中斷服務例程(或類似)我會使整個數據結構來波動可能訪問。

+0

感謝您的例子(假設你的意思是「通過'nonVolatilePtr'」) – Toby

+0

@Toby良好的漁獲:)編輯 – mziccard

+0

爲了澄清,你的意思我至少需要'揮發性INT * PTR = volatileVar;'或'揮發性INT * volatile ptr =&volatileInt;'? – Toby