Здравствуйте, Аноним, Вы писали:
А>>>Справедливо ли sizeof(void*)==sizeof(T*) А>>>где Т — любой тип
E>>Нет.
А>спасибо А>но хотелось бы немного подробней, почему и в каких случаях
Потому что стандарт гарантирует лишь совпадение внутреннего представления указателя на void с внутренним представлением указателя на символьные типы. Относительно других типов такой гарантии не дается.
Представьте себе платформу, в которой минимальной адресуемой единицей памяти является 32-разрядное слово. Адрес также 32-разрядный. Реализация C/C++ для такой платформы может хранить объекты типа char упакованными по четыре в одном слове. Таким образом, char* (и, соответственно, void*) будут представлены двумя словами, одно из которых хранит адрес слова, а другое — номер символа в этом слове. Тогда как для хранения указателя на int достаточно будет одного 32-разрядного слова.
K>а потому что я хладнокровный человек с нордическим характером.
везет. наверное, начальнику ты ответил "нет", раз в форум написал "да" ?
Of course, the code must be complete enough to compile and link.
Re[4]: void*
От:
Аноним
Дата:
21.10.04 08:54
Оценка:
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>>>Справедливо ли sizeof(void*)==sizeof(T*) А>>>>где Т — любой тип
E>>>Нет.
А>>спасибо А>>но хотелось бы немного подробней, почему и в каких случаях
E>Потому что стандарт гарантирует лишь совпадение внутреннего представления указателя на void с внутренним представлением указателя на символьные типы. Относительно других типов такой гарантии не дается.
E>Представьте себе платформу, в которой минимальной адресуемой единицей памяти является 32-разрядное слово. Адрес также 32-разрядный. Реализация C/C++ для такой платформы может хранить объекты типа char упакованными по четыре в одном слове. Таким образом, char* (и, соответственно, void*) будут представлены двумя словами, одно из которых хранит адрес слова, а другое — номер символа в этом слове. Тогда как для хранения указателя на int достаточно будет одного 32-разрядного слова.
E> <...> char* (и, соответственно, void*) будут представлены двумя словами, одно из которых хранит адрес слова, а другое — номер символа в этом слове. Тогда как для хранения указателя на int достаточно будет одного 32-разрядного слова.
Здравствуйте, SWW, Вы писали:
E>> <...> char* (и, соответственно, void*) будут представлены двумя словами, одно из которых хранит адрес слова, а другое — номер символа в этом слове. Тогда как для хранения указателя на int достаточно будет одного 32-разрядного слова.
SWW>Интересная гипотеза. А на самом деле такие есть?
Если мне не изменяет склероз, упакованные символы были на IBM 360/370. Но компиляторов C для них я не встречал. Не знаю, существовали ли такие.
Здравствуйте, elcste, Вы писали:
E>Если мне не изменяет склероз, упакованные символы были на IBM 360/370.
Склероз вам изменяет. Архитектура IBM 360/370 (ЕС ЭВМ) прекрасно работали со строками символов. Машина нормально адресовала память побайтно и требования о том, чтобы в строковых операциях указатель ссылался только на границу слова (двойного слова и т.д.) не было. Там не было нулевого байта в конце строки, как правило применялась немного другая технология для обозначения длин строк. Но в остальном это была совершенно нормальная архитектура.
E>Но компиляторов C для них я не встречал. Не знаю, существовали ли такие.
Чаще всего на ЕС ЭВМ работала ОС ЕС. Под ОС ЕС мне не приходилось встречать компиляторов языка С. Возможно он и был, я об этом ничего не знаю.
Была ещё одна операционная система, так называемая Система Виртуальных Машин (СВМ). Так вот, под этой операционкой мне приходилось видеть полноценную реализацию UNIX-а. И, конечно же, там был компилятор с языка С.
Если интересно, могу рассказать подробнее, только это всё уже такие анахронизмы... Носит чисто познавательный интерес.
... << RSDN@Home 1.1.4 beta 3 rev. 194>>
Re[4]: void*
От:
Аноним
Дата:
21.10.04 12:59
Оценка:
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>>>Справедливо ли sizeof(void*)==sizeof(T*) А>>>>где Т — любой тип
E>>>Нет.
А>>спасибо А>>но хотелось бы немного подробней, почему и в каких случаях
E>Потому что стандарт гарантирует лишь совпадение внутреннего представления указателя на void с внутренним представлением указателя на символьные типы. Относительно других типов такой гарантии не дается.
E>Представьте себе платформу, в которой минимальной адресуемой единицей памяти является 32-разрядное слово. Адрес также 32-разрядный. Реализация C/C++ для такой платформы может хранить объекты типа char упакованными по четыре в одном слове. Таким образом, char* (и, соответственно, void*) будут представлены двумя словами, одно из которых хранит адрес слова, а другое — номер символа в этом слове. Тогда как для хранения указателя на int достаточно будет одного 32-разрядного слова.
а для Win32 Linux/Unix это справедливое утверждение ?
На самом деле, можно не волноваться за габариты sizeof(void*), sizeof(T*).
Вне зависимости от внутреннего представления, Стандартом гарантировано, что они конвертируются друг в друга "без потерь". (4.10.2)
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, elcste, Вы писали:
К>На самом деле, можно не волноваться за габариты sizeof(void*), sizeof(T*). К>Вне зависимости от внутреннего представления, Стандартом гарантировано, что они конвертируются друг в друга "без потерь". (4.10.2)
Более того можно так же не волноватся насчет sizeof(void*), sizeof(T*) и стандарта. Т.к. платформы в которых sizeof(void*) != sizeof(T*) лично мной не поддерживаются . Пусть те извращенцы которые создают такие платформы поищут себе таких же извращенцев программистов.
Re[6]: void*
От:
Аноним
Дата:
21.10.04 14:10
Оценка:
Здравствуйте, Kluev, Вы писали:
K>Здравствуйте, Кодт, Вы писали:
К>>Здравствуйте, elcste, Вы писали:
К>>На самом деле, можно не волноваться за габариты sizeof(void*), sizeof(T*). К>>Вне зависимости от внутреннего представления, Стандартом гарантировано, что они конвертируются друг в друга "без потерь". (4.10.2)
K>Более того можно так же не волноватся насчет sizeof(void*), sizeof(T*) и стандарта. Т.к. платформы в которых sizeof(void*) != sizeof(T*) лично мной не поддерживаются . Пусть те извращенцы которые создают такие платформы поищут себе таких же извращенцев программистов.
Здравствуйте, Кодт, Вы писали:
К>На самом деле, можно не волноваться за габариты sizeof(void*), sizeof(T*). К>Вне зависимости от внутреннего представления, Стандартом гарантировано, что они конвертируются друг в друга "без потерь". (4.10.2)
Чуточку надо уточнить.
T* -> void* — преобразовывается без потерь;
void* -> T* — преобразовывается без потерь, но при условии, что void* был получен результатом преобразования T* -> void*.
Я кончил, джентльмены, мне остается только поблагодарить вас за внимание.
Здравствуйте, achp, Вы писали:
К>>На самом деле, можно не волноваться за габариты sizeof(void*), sizeof(T*). К>>Вне зависимости от внутреннего представления, Стандартом гарантировано, что они конвертируются друг в друга "без потерь". (4.10.2)
A>Чуточку надо уточнить.
A>T* -> void* — преобразовывается без потерь; A>void* -> T* — преобразовывается без потерь, но при условии, что void* был получен результатом преобразования T* -> void*.
Даже если T — это класс с множественным виртуальным наследованием?
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Здравствуйте, AndrewJD, Вы писали:
A>>Чуточку надо уточнить.
A>>T* -> void* — преобразовывается без потерь; A>>void* -> T* — преобразовывается без потерь, но при условии, что void* был получен результатом преобразования T* -> void*.
AJD>Даже если T — это класс с множественным виртуальным наследованием?
Здравствуйте, Dervish, Вы писали:
E>>Если мне не изменяет склероз, упакованные символы были на IBM 360/370. D>Склероз вам изменяет. Архитектура IBM 360/370 (ЕС ЭВМ) прекрасно работали со строками символов.
Да, это я пытался дезинформировать общественность. На IBM 360/370 адресация была побайтная.
Немного поискал. Оказалось, что BCPL и B разрабатывались на архитектурах с пословной адресацией.
The machines on which we first used BCPL and then B were word-addressed, and these languages' single data type, the `cell,' comfortably equated with the hardware machine word. The advent of the PDP-11 exposed several inadequacies of B's semantic model. First, its character-handling mechanisms, inherited with few changes from BCPL, were clumsy: using library procedures to spread packed strings into individual cells and then repack, or to access and replace individual characters, began to feel awkward, even silly, on a byte-oriented machine.
B works tolerably well on the H6070, which is a word addressable machine; when using a byte addressable machine such as the IBM 360/370 models or the PDP-11, B seems less attractive. A successor language, C, is being developed which allows most of the advantages of B on byte addressable machines, as well as a structure capability. While the case for C on the H6070 is not as strong as it is on byte addressable machines, the structure and character manipulation capabilities make it likely that C will eventually appear on the H6070.
Реализация C для Honeywell 6070 существовала, Керниган упоминает в Programming in C: A Tutorial, что int в ней был 36-битным, а char 9-битным. Но информации об устройстве указателей на символы я опять-таки не нашел.
D>Если интересно, могу рассказать подробнее, только это всё уже такие анахронизмы... Носит чисто познавательный интерес.
А я студенческий опыт работы на этих монстрах забыл, как страшный сон.
Здравствуйте, Аноним, Вы писали:
E>>Представьте себе платформу, в которой минимальной адресуемой единицей памяти является 32-разрядное слово.
А>а для Win32 Linux/Unix это справедливое утверждение ?
Win32 пока работает исключительно на архитектурах с побайтной адресацией. Т.е., строго говоря, реализация C/C++, в которой sizeof(void*) был бы больше sizeof(int*), может быть и под Win32, но это было бы... гм, странно как-то.
Обо всех аппаратных платформах, где может работать нечто *nix-подобное, судить не возьмусь.
Здравствуйте, elcste, Вы писали:
D>>Если интересно, могу рассказать подробнее, только это всё уже такие анахронизмы... Носит чисто познавательный интерес.
E>А я студенческий опыт работы на этих монстрах забыл, как страшный сон.
А мне очень нравилось. Даже немного жаль, что эти машины ушли в прошлое.
Здравствуйте, McSeem2, Вы писали:
MS>Здравствуйте, Dervish, Вы писали:
D>>Но в остальном это была совершенно нормальная архитектура.
MS>...за исключением того, что там не было аппаратного стэка
Верно. Но там вся архитектура и операционка была не реентерабельная. Равно как и системы программирования. Например, Fortran-IV, он, собственно, тоже не отличался реентерабельностью. И стека не требовал.
Здравствуйте, AndrewJD, Вы писали:
A>>T* -> void* — преобразовывается без потерь; A>>void* -> T* — преобразовывается без потерь, но при условии, что void* был получен результатом преобразования T* -> void*.
AJD>Даже если T — это класс с множественным виртуальным наследованием?
The machines on which we first used BCPL and then B were word-addressed, and these languages' single data type, the `cell,' comfortably equated with the hardware machine word. The advent of the PDP-11 exposed several inadequacies of B's semantic model. First, its character-handling mechanisms, inherited with few changes from BCPL, were clumsy: using library procedures to spread packed strings into individual cells and then repack, or to access and replace individual characters, began to feel awkward, even silly, on a byte-oriented machine.
E>
B works tolerably well on the H6070, which is a word addressable machine; when using a byte addressable machine such as the IBM 360/370 models or the PDP-11, B seems less attractive. A successor language, C, is being developed which allows most of the advantages of B on byte addressable machines, as well as a structure capability. While the case for C on the H6070 is not as strong as it is on byte addressable machines, the structure and character manipulation capabilities make it likely that C will eventually appear on the H6070.
Гм... А мне казалось, что у PDP-11 (КР1801ВМ1) именно пословная организация памяти...
Я кончил, джентльмены, мне остается только поблагодарить вас за внимание.
Здравствуйте, Dervish, Вы писали:
MS>>...за исключением того, что там не было аппаратного стэка
D>Верно. Но там вся архитектура и операционка была не реентерабельная. Равно как и системы программирования. Например, Fortran-IV, он, собственно, тоже не отличался реентерабельностью. И стека не требовал.
...так выпьем же за реентерабельность прерываний!
На самом деле, существовали определенные соглашения, какой регистр использовать под указатель программного стэка. Таким образом, PL/I был вполне реентерабельным языком.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
D>>Верно. Но там вся архитектура и операционка была не реентерабельная. Равно как и системы программирования. Например, Fortran-IV, он, собственно, тоже не отличался реентерабельностью. И стека не требовал.
MS>...так выпьем же за реентерабельность прерываний!
Ну да, поймали вы меня. Фраза действительно некорректная.
MS>На самом деле, существовали определенные соглашения, какой регистр использовать под указатель программного стэка.
13-й регистр. Всего было 16 регистров, в момент вызова любой функции 13-й регистр должен был содержать область памяти, в которую вызываемая функция могла бы сбросить состояние регистров на момент вызова. Если функция не вызывает другие функции, то ей делать ничего не нужно. А если вызывает, то она должна приготовить аналогичный блок памяти, в который будет сохранять регистры уже вызываемая функция.
Пока нет в программе рекурсии, область памяти для сброса регистров можно выделять статически. Как правило так и делали. Но если есть рекурсия, то тут уже ничего не поделаешь, приходилось обращаться к аллокатору и выделять память из кучи, поскольку аппаратной поддержки стека не было. Либо эмулировать стек каким-то своим способом.
MS>Таким образом, PL/I был вполне реентерабельным языком.
Не было у меня дружбы с PL/I. Но он действительно был реентерабельным. Реализация — см.выше.
Здравствуйте, Dervish, Вы писали:
D>Пока нет в программе рекурсии, область памяти для сброса регистров можно выделять статически. Как правило так и делали. Но если есть рекурсия, то тут уже ничего не поделаешь, приходилось обращаться к аллокатору и выделять память из кучи, поскольку аппаратной поддержки стека не было. Либо эмулировать стек каким-то своим способом.
Не могу утверждать на 100%, в те времена я был глупым студентом, но по-моему, даже на FORTRAN-IV рекурсия вполне допускалась. В конце концов, что такое аппаратный стэк? Не более чем небольшая автоматизация
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.