Почему при использовании типа данных make «неявное преобразование теряет целочисленную точность» исчезает? - PullRequest
0 голосов
/ 26 апреля 2018

Я знаю, что есть много вопросов с этим названием, но я не ищу решения. Я хотел бы знать, почему это работает. Я дал это как решение

int points[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int *pos = points + 5;

int index = pos - points;

но когда я использую этот код, я получаю предупреждение, что неявное преобразование теряет целочисленную точность: от 'long' до 'int'. Теперь, когда я использую long вместо типа данных индекса

int points[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int *pos = points + 5;

long index = pos - points;

это не дает предупреждения. Я пытался использовать долго, потому что я вспомнил кое-что о указателях и долго. Но у указателей нет типа данных (если я ошибаюсь, поправьте меня). Обе точки и * pos инициализируются с помощью int. Так почему long fit, а int нет?

Почему они используют int в решении? Это неправильное решение или дело в xCode (с которым я работаю)?

Спасибо, что ответили

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

но когда я использую этот код, я получаю предупреждение, что неявное преобразование теряет целочисленную точность: от 'long' до 'int'.

Это означает, что на вашей платформе , разница двух указателей имеет тип long.

Я пытался использовать long, потому что я кое-что вспомнил об указателях и long. Но у указателей нет типа данных (если я ошибаюсь, поправьте меня).

Вы ошибаетесь, у всех есть тип в C. У указателей есть типы указателей . Разница между двумя указателями заключается в целочисленном типе со знаком, но в стандарте не указывается, какие из них используются разными платформами.

Но в стандарте указывается typedef по имени ptrdiff_t (определено в stddef.h), которое должно быть определено для целочисленного типа со знаком разницы в указателях, так что это тип, который вы должны используйте для того типа кода, который вы показываете.

Обе точки и * pos инициализируются с помощью int. Так почему long fit, а int нет?

Указатели типов, на которые указывают указатели, отличаются от самих указателей. Указатели - это адреса, и в вашей системе адреса могут быть больше, чем int значений.

Почему они используют int в решении? Это неправильное решение

Да, это неправильно. Как объяснялось выше, выражение pos - points - это некоторый целочисленный тип со знаком, и это может быть int на некоторых платформах, но вы не можете предположить, что.

Конечно, было бы хорошо и следующее:

int points[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int *pos = points + 5;

int index = (int)(pos - points);

В этом примере вы знаете, что результат может быть представлен в int, поэтому вы можете просто преобразовать его явным приведением. Но не делайте этого в общем .

0 голосов
/ 26 апреля 2018

index = pos - points; - это вычитание между двумя указателями, где тип должен быть ptrdiff_t.

Вот описание стандарта C11, проект N1570 § 6.5.6:

9. Когда вычтены два указателя, оба должны указывать на элементы тот же объект массива, или один за последним элементом массива объект; В результате разница индексов двух элементы массива. Размер результата определяется реализацией, и его тип (целочисленный тип со знаком) равен ptrdiff_t , определенному в <stddef.h> header.

В вашей системе бывает, что тип ptrdiff_t, вероятно, имеет значение от typedef до long, как упомянуто в комментариях @FelixPalmen, поэтому компилятор жалуется, когда вы объявляете index как int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...