Дилемма представления двух указателей - PullRequest
2 голосов
/ 06 апреля 2019

Я не понимаю, как машина может иметь более одного представления указателя. Следующий из GNU говорит:

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

Как это возможно?Какова связь между высказыванием и #define SEM_FAILED ((sem_t*)-1)?Что делает последний?Я знаю, что это нулевой указатель, который имеет постоянное значение.Но как он представлен в памяти, поскольку он указывает на -1?А что, если он указывает на правильное место?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2019

Одной из самых первых архитектур, на которые ориентировался С, были архитектуры с 36-битными или 18-битными словами (тип int).Только слова были непосредственно адресуемы по адресам, таким как 0, 1, 2, используя родные указатели.Однако одно слово для одного символа потратило бы слишком много памяти, поэтому был добавлен 9-битный тип char, с 2 или 4 символами в одном слове.Поскольку они не были бы адресуемы указателем слова, char * был сделан из двух слов: одно указывало на слово, а другое сообщало, каким из байтов в слове следует манипулировать.

Конечно, сейчаспроблема в том, что char * имеет ширину в два слова, тогда как int * - это всего лишь одно, и это имеет значение при вызове функции без прототипа или с многоточием - тогда как (void*)0 будет иметь представление, совместимое с (char *)0, это не будетбыть несовместимым с (int *)0, поэтому требуется явное приведение.


Есть еще одна проблема с NULL.Хотя GCC, похоже, гарантирует, что NULL будет иметь тип void *, стандарт C не гарантирует этого, поэтому даже использование NULL в вызове функции, подобном execl, который ожидает char * s в качестве аргументов переменной, является неправильнымбез приведения, потому что реализация может определить

#define NULL 0

(sem_t*)-1 не является указателем NULL, это целое число -1, преобразованное в указатель с определенным реализацией Результаты.В системах POSIX это (по необходимости) приведет к адресу, который никогда не может быть местоположением любого sem_t.

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

1 голос
/ 08 апреля 2019

Я полагаю, это намекает на "ближний" и "дальний" указатели, встречающиеся в некоторых 16-битных архитектурах? Из того, что я понимаю, они использовали различные масштабные смещения для обхода всего лишь 64 КБ адресного пространства.

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