2015-05-29 2 views
2

На каком-то встроенном устройстве я передал unsigned char указатель на atoiбез актерский состав.Передать знак без знака в atoi без литья

unsigned char c[10]="12"; 
atoi(c); 

Вопрос: он четко определен?

I saw где-то нормально для строковых функций, но не был уверен в atoi.

Редактировать: Btw. Некоторые проблемы были высказаны по одному из нижеприведенных ответов, что может быть не так хорошо даже для строковых функций, таких как strcpy, - но если бы я получил право (?), То это означало и то, что на практике это может быть в порядке.


Кроме того, что я здесь, это нормально, чтобы сделать следующее присвоение к unsigned char указатель слишком хорошо? Потому что я использовал какой-то инструмент, который жалуется «Несоответствие типа (назначения) (PTRS подписанного/без знака)»

unsigned char *ptr = strtok(unscharbuff,"-"); 
    // is assignment also ok to unsigned char? 

ответ

1

Да, это будет работать прекрасно. Настройки вашего компилятора будут определять, будет ли вы получать предупреждение о типе. Обычно я компилирую с помощью -Wall, чтобы включить все предупреждения, а затем использовать статический кастинг в коде для каждого случая, так что я знаю, что внимательно изучил их. Конечным результатом являются нулевые ошибки и нулевые предупреждения, и любое изменение, которое вызывает предупреждение в будущем, действительно будет выделяться, а не потеряться в 100 переносимых сообщениях.

+0

как я уже сказал, я не использовал литье; ps это компилятор для некоторого встроенного устройства. –

+1

. Вы не использовали приведения, но вы должны сделать это, чтобы отключить предупреждения и запретить включение предупреждений ('-Wall'), чтобы получить полезные предостережения от компилятора. – chqrlie

+0

@chqrlie: Хорошо, я не был уверен, как пройти -Wall к этому компилятору Я использую некоторый файл make и т. Д. Не был уверен, поддерживает ли этот компилятор -Wall? –

5

Нет, это не совсем правильно. Это нарушение ограничений, требующее диагностики времени компиляции. На практике это очень вероятно, что вы будете работать, как вы ожидаете, но это не гарантируется, и ИМХО это плохой стиль.

atoi функция объявлена ​​в <stdlib.h> как:

int atoi(const char *nptr); 

Вы пропускание unsigned char* аргумента функции, ожидающую char* аргумента. Эти два типа несовместимы, и нет никакого неявного преобразования из одного в другое. Соответствующий компилятор может выдать предупреждение (которое считается диагностическим), а затем продолжить генерировать исполняемый файл, но поведение этого исполняемого файла не определено.

Начиная с C99, вызов функции без видимой декларации является нарушением ограничения, поэтому вы не можете избежать этого, опуская #include <stdlib.h>.

C все же разрешает вызовы функций с видимым объявлением, где объявление не является прототипом (т. Е. Не определяет количество типов (типов) параметров). Таким образом, вместо обычного #include <stdlib.h>, вы можете добавить свою собственную декларацию:

int atoi(); 

, который позволил бы называть его с unsigned char* аргументом.

Это почти наверняка «работает», и может быть возможно построить аргумент из стандарта, чтобы его поведение было четко определено.В char и unsigned char значения '1' и '2' гарантированно иметь такое же представление

Но это гораздо проще добавить бросание чем доказать, что это не нужно - или, еще лучше, чтобы определить c как массив char а не как массив из unsigned char, так как он предназначен для хранения строки.

unsigned char *ptr = strtok(unscharbuff,"-"); 

Это также является нарушением ограничения. Нет никакого неявного преобразования из unsigned char* в char* для первого аргумента в вызове strtok, и нет никакого неявного преобразования из char* в unsigned char* для инициализации ptr.

+0

@userq: Нет, это нарушение ограничений. После неявного преобразования '' Test "' дает значение типа 'char *'. Нет никакого неявного преобразования из 'char *' в 'unsigned char *'. –

+0

@userq: 'unsigned char arr [] =" Test ";' разрешено. Нет никакого преобразования указателя; элементы строкового литерала используются для инициализации элементов 'unsigned char' массива ([N1570] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 6.7.9p14). Это относится только к инициализации массива, а не инициализации указателя. Если я сказал иначе, вы можете ссылаться на соответствующий ответ, чтобы я мог его исправить? –

Смежные вопросы