Этот код работает на Turbo C, но не на компиляторе GCC? - PullRequest
1 голос
/ 06 ноября 2011

Этот код работает на Turbo C, но не на компиляторе gcc
Ошибка: синтаксическая ошибка перед маркером '*'

#include<stdio.h>
int main()
{
char huge *near *far *ptr1;
char near *far *huge *ptr2;
char far *huge *near *ptr3;
printf("%d, %d, %d\n", sizeof(ptr1), sizeof(ptr2), sizeof(ptr3));
return 0;
}

Выход Turbo C: 4, 4, 2
Можете ли вы объяснить выход на Turbo C?

Ответы [ 3 ]

6 голосов
/ 06 ноября 2011

Квалификаторы huge, far и near, нестандартные .Поэтому, хотя они могут работать в Turbo C, вы не можете полагаться на то, что они работают в других компиляторах (таких как gcc).

5 голосов
/ 06 ноября 2011

Компиляторы Borland C / C ++ для DOS поддерживали несколько моделей памяти.

Модель памяти - это способ доступа к коду и данным через указатели.

Поскольку DOS работает в так называемой real mode ЦП, в котором доступ к памяти осуществляется через пары segment value и offset value (каждая обычно имеет длину 16 бит), адрес памяти, естественно, имеет длину 4 байта.

Но сегментзначения не всегда должны быть указаны явно.Если все, что нужно программе для доступа, содержится в одном segment (блок памяти размером 64 КБ, выровненный по 16-байтовой границе), достаточно одного значения сегмента, и как только оно загружено в регистры сегментов ЦП (CS, SS, DS), ES), программа может получить доступ ко всему, используя только 16-битные смещения.Кстати, многие программы типа .COM работают точно так же, они используют только один сегмент.

Итак, у вас есть 2 возможных способа доступа к памяти, с явным значением сегмента или без.

В этих строках:

char huge *near *far *ptr1;
char near *far *huge *ptr2;
char far *huge *near *ptr3;

модификаторы far, huge и near определяют близость объектов, на которые будут указывать ptr1, ptr2 и ptr3.Они сообщают компилятору, что объекты *ptr1 и *ptr2 будут «далеко» от основного / текущего сегмента (ов) программы, то есть они будут находиться в некоторых других сегментах, и, следовательно, к ним нужно обращаться через 4-байтовые указатели, и объект *ptr3 находится "рядом" в пределах собственного сегмента (ов) программы, и достаточно двухбайтового указателя.

Это объясняет различные размеры указателя.

В зависимости от модели памяти, которую вы выбираете для своей программы для компиляции, указатели функций и данных по умолчанию будут либо near, либо far, либо huge и избавят вас от их явного наложения, если только вам не нужноуказатели по умолчанию.

Модели памяти программ:

  • крошечные: 1 сегмент на все;ближние указатели
  • small: 1 сегмент кода, 1 сегмент данных / стек;ближние указатели
  • средний: несколько сегментов кода, 1 сегмент данных / стек;указатели удаленного кода, указатели рядом с данными
  • compact: 1 сегмент кода, несколько сегментов данных;ближние указатели кода, дальние указатели данных
  • большой: несколько сегментов кода и данных;дальние указатели
  • огромные: несколько сегментов кода и данных;огромные указатели

Huge указатели не имеют определенных ограничений на far указатели, но работают медленнее.

1 голос
/ 06 ноября 2011

вы забыли поставить запятую между переменными :).Переменные не могут иметь одинаковые имена, если их область действия одинакова.

...