這是我在這里的第一個問題,我想。我寫我的 C 代碼試圖尊重“-Wall -Wextra -Werror -ansi -pedantic”,但我可以很靈活。
我用以下原型撰寫了一個函式:
int messagequeue_add(messagequeue_t *p_queue, char* p_msg, const size_t p_size)
我在這個函式中使用“realloc(p_msg, XXX)”。因此,它不應該接收字串文字指標,而只能接收動態指標。如果可能使用標準 C89 或 C99 ,如何在函式原型中禁止字串文字指標并僅允許字串動態指標
我已經遇到過在其原型引數中不允許使用文字字串的函式(編譯時的錯誤/警告),但我不記得它是在哪里以及如何定義的。
我嘗試了很多谷歌,去了我的整個紙質圖書館,這個問題太具體了,不可能在大海撈針中找到針。我很有經驗,但這次我確實需要幫助。
完整的功能代碼是:
int messagequeue_add(messagequeue_t *p_queue, char* p_msg, const size_t p_size) {
messagequeueitem_t l_messagequeueitem;
/* Parameters sanity checks for early return */
if (!p_queue) {
warnx("%s:%s():%d (%s@%s): p_queue can not be NULL",
__FILE__, __func__, __LINE__, __DATE__, __TIME__);
return -1;
}
if (!(*p_queue)) {
warnx("%s:%s():%d (%s@%s): *p_queue can not be NULL",
__FILE__, __func__, __LINE__, __DATE__, __TIME__);
return -1;
}
if ((!p_msg)&&(p_size)) {
warnx("%s:%s():%d (%s@%s): p_msg can not be NULL with p_size>0",
__FILE__, __func__, __LINE__, __DATE__, __TIME__);
return -1;
}
ASSERT(p_queue);
ASSERT(*p_queue);
ASSERT( ((NULL==(*p_queue)->head)&&(NULL==(*p_queue)->tail))
||((NULL!=(*p_queue)->head)&&(NULL!=(*p_queue)->tail)));
ASSERT((p_msg)||((!p_msg)&&(!p_size)));
/* Create messagequeueitem_t structure */
if (NULL == ((l_messagequeueitem) = (messagequeueitem_t)malloc(sizeof(struct messagequeueitem_s)))) {
warn("%s:%s():%d (%s@%s): malloc failed",
__FILE__, __func__, __LINE__, __DATE__, __TIME__);
return -1;
}
ASSERT(l_messagequeueitem);
l_messagequeueitem->size = p_size;
l_messagequeueitem->next=NULL;
/* Do not create a copy of the message but take ownership of the allocated
* contents. */
/* Resize the memory allocation to fit in the case sizeof(p_msg) != p_size */
DBG_PRINTF("p_msg=%p",p_msg);
if (NULL == ( l_messagequeueitem->msg = realloc( p_msg, l_messagequeueitem->size))) {
warn("%s:%s():%d (%s@%s): realloc failed",
__FILE__, __func__, __LINE__, __DATE__, __TIME__);
free(l_messagequeueitem);
return -1;
}
if ((*p_queue)->tail)
(*p_queue)->tail->next = l_messagequeueitem;
else
(*p_queue)->head = l_messagequeueitem;
(*p_queue)->tail = l_messagequeueitem;
return 0;
}
uj5u.com熱心網友回復:
我用以下原型撰寫了一個函式:
int messagequeue_add(messagequeue_t *p_queue, char* p_msg, const size_t p_size)我在這個函式中使用“realloc(p_msg, XXX)”。因此,它不應該接收字串文字指標,而只能接收動態指標。如果可能使用標準 C89 或 C99,如何在函式原型中禁止字串文字指標并僅允許字串動態指標
標準 C 的任何版本都沒有提供一種機制來區分指向字串文字的指標 (in) 和指向字符的其他指標。字串字面量表示的陣列元素具有 type char,因此指向它們的指標可以具有 type char *,C 沒有指定任何元資料的存在,通過這些元資料可以將它們與相同型別的其他值區分開來。
這通常通過編碼約定來處理。具體來說,作為代碼約定的問題,
指向或指向字串文字的指標只能分配給作為
const資料指標的變數和函式引數,并且const嚴格遵守正確性(沒有拋棄const或以其他方式拋棄它)。
這意味著在您想要接受可能指向字串文字的指標的地方,您使用 type const char *。
遵守此類約定排除了將指向字串文字的指標提供給需要指向可修改資料的指標的代碼。
特定的編譯器可能會提供有用的功能。例如,許多有方法為違反const正確性生成警告和/或錯誤。有些具有專門用于檢測修改字串文字的嘗試的選項。例如,如果您使用 GCC 編譯并啟用其靜態分析器,那么它將檢測(至少一些)寫入const資料和字串文字的嘗試。
但
您對問題的描述過于狹隘。如果您希望能夠realloc()將p_msg指標傳遞給您的函式,那么該指標必須先前已通過動態分配獲得(而不是自free()d 以來)。這比它不指向字串文字要強得多,因此專注于字串文字角度可能不是那么有用。
您絕對應該記錄此要求,并且應該將該要求適當地傳播到其他功能的檔案中。但是,如果要求僅僅是可以修改指向的資料,那么您不太可能獲得編譯器幫助。C 不提供任何值或資料型別屬性來描述可修改但不可取消/重新分配的資料。但是,有一些工具可以在運行時檢測此類問題。例如,Valgrind 可以做到這一點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/524307.html
上一篇:是否可以在C中復雜化指標?
