2012-02-21 2 views
1

У меня есть унаследованный код, который содержит следующий код логику:Приведения Unsigned Long Долго Character указателя в C

unsigned long long address; /* Its content = Some Address, not a normal value */ 

strcmp (address, (const char*)some_char_buffer); 

Это дает предупреждение с НКОЙ.

Может ли кто-нибудь предложить какой-то способ приведения переменной «address» в указатель char, чтобы он мог быть правильно декодирован, а gcc не дает никаких предупреждений?

+0

Я хотел бы отметить, что вы должны использовать 'intptr_t' или' uintptr_t' из 'stdint.h' для хранения значений указателя в виде целых чисел. В противном случае вы рискуете потерять точность (или, наоборот, получить точность, которая будет потеряна при обратном преобразовании и может вызвать подобные проблемы). –

+0

Если бы не было никаких проблем, Крис, это не был бы устаревший код ... В рамках усилий по модернизации ваша рекомендация разумна. Я отмечаю, что выражение 'const char *' в вопросе, вероятно, не требуется, если 'some_char_buffer' на самом деле' unsigned char' (или, что менее вероятно, 'signed char'). –

+0

@JonathanLeffler - У меня есть ужасная тенденция пропустить часть кода, и я полностью пропустил слова «код устаревших» в первой строке. Я чувствую себя немного глупо сейчас ... –

ответ

-2

Попробуйте это:

strcmp((char*)&address, (const char*)some_char_buffer); 
2

Предполагая, что содержание address действительно только указатель: Вы, вероятно, можно сделать следующее:

strcmp ((char*)address, (const char*)some_char_buffer); 

Но если это так, то было бы намного лучше вместо этого следует изменить адрес char* везде:

char* address; 

В зависимости от вашей кодовой базы, которая может быть более крупной. Знаете ли вы, почему это был unsigned long long, а не указатель в первую очередь?


В качестве альтернативы, если вы хотите байт содержания address следует рассматривать как строку: (а не содержание, которое address может указывать на), сделайте следующее:

strcmp ((char*)&address, (const char*)some_char_buffer); // note the & 

Примечание что вам понадобится последний байт в длинном, чтобы быть '\0' в этом случае. Если это то, что вы хотите сделать, я бы рекомендовал использовать strncmp() ограниченные по размеру долго долго вместо:

strncmp((char*)&address, (const char*)some_char_buffer, 
     sizeof(unsigned long long)); 
+0

'NULL' (' (void *) 0') является нулевым указателем, ASCII NUL ('' \ 0'') - это то, что приходит в конце строки C. Они не взаимозаменяемы, даже если они имеют одинаковое значение. –

+0

@ChrisLutz Совершенно верно, исправлено :) –

2

Ваш код должен, вероятно, используя uintptr_t для address. (Я не думаю, что стандарт дает гарантию того, что unsigned long long имеет достаточное количество бит для хранения указателя, даже если он часто делает на практике.)

uintptr_t address = ...; 
strcmp((const char *)address, some_char_buffer); 

или это, или, если вы можете жить с уродством,

unsigned long long address = ...; 
strcmp((const char *)(uintptr_t)address, some_char_buffer); 
+0

+1 за рекомендацию 'uintptr_t' –

+4

Практически не выгодно выполнять листинг через' uintptr_t' во втором варианте. Если значение в 'address' было уже усечено, то уже слишком поздно. – caf

+0

Хорошо, что вам нужно закрыть gcc во втором варианте, например, если вы (по какой-либо причине) присваиваете результат 'strtoull' переменной' address'. В самом деле, первый из них ('uintptr_t address = strtoul ...') был бы предпочтительнее, поскольку один актерский состав может быть заменен неявным преобразованием. –