Важная информация
Показано с 1 по 10 из 10

Тема: #PRAGMA - что это?

  1. #1 #PRAGMA - что это? 
    Профи Аватар для stabud
    Регистрация
    05.01.2013
    Сообщений
    784
    Сказал(а) спасибо
    326
    Поблагодарили 348 раз(а) в 275 сообщениях
    Записей в блоге
    6
    Пишу в раздел С++, поскольку думаю , что на этом языке наверно лучше знают об этой директиве. Так покопавшись по интернету , я не смог понять значимость этой директивы. Везде описание очень сухое и невнятное. Меня интересует для чего она в большей степени нужна.
    Ответить с цитированием  
     

  2. #2  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 249 раз(а) в 164 сообщениях
    куча разных применений.
    ИМХО, ей лучше вообще не пользоваться.
    ИМХО, это не стандартная директива (в стандарте ее нет), поэтому используют ее разные компиляторы по-разному.

    После слова прагма идет значение.

    Например, прагмой можно изменить точку входа:
    #pragma comment(linker,"/ENTERY:WinMain")

    по умолчанию точка входа - это функция main(), но можно замутить другую, иногда в этом есть смысл.

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

    есть
    pragma pack - вот этой штукой я пользовался, и даже студентов ей пытал. Есть такая штука в С++, как выравнивание полей в структурах.

    грубо говоря

    struct T {
    char c;
    };

    sizeof(T); // какое значение вернет sizeof? -

    студенты могут считать что 1, ну и по хреновым методичкам оно там и есть, но а реально все зависит от того, как выравнивает поля компилятор, а управлять этим можно с pragma pack

    Еще часто пользуют pragma once чтобы модуль включался при линковке только один раз. Но вместо pragma once всегда можно использовать #ifndef и #define. Вобщем в основном так и делают.

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

    Вот такая штука эта прагма, я то стараюсь писать портируемый код, поэтому ими не балуюсь. Ну мало ли, напишу я софтину и захочу ее на ведре запустить, но где гарантии, что компилятор С++ на ведре сработает также как компилятор мелкософта или гцц? - никто таких гарантий не дает (и никто не обязан это обеспечивать).

    В стандарте я ее чесно не искал, поэтому ИМХО всюду написал.
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  3. 2 пользователя(ей) сказали cпасибо:

    >Quiet Snow< (03.04.2014), stabud (03.04.2014)

  4. #3  
    Профи Аватар для stabud
    Регистрация
    05.01.2013
    Сообщений
    784
    Сказал(а) спасибо
    326
    Поблагодарили 348 раз(а) в 275 сообщениях
    Записей в блоге
    6
    Благодарю rrrFer!

    И уж раз зашла речь про выравнивания полей, то здесь у меня тоже недопонимания. Я только один раз столкнулся с этим, когда мой код не хотел работать. Весь мозг себе тогда запарил. Один и тот же код на MASM работал как нужно, а на FB нифига. И вроде все по делу было и заголовки WINAPI и сам код, но оказалось, что там в заголовке надо было установить выравнивание полей структуры. Я так понял что данная бяка в разных языках может быть уникальная или я не прав?
    Ответить с цитированием  
     

  5. #4  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 249 раз(а) в 164 сообщениях
    Я так понял что данная бяка в разных языках может быть уникальная или я не прав?
    Вобще она зависит от архитектуры (потому как архитектура тоже накладывает ограничения), но больше от компилятора.
    Вот в некоторых (в большинстве) компиляторов С++ можно этот параметр варьировать, но не желательно.
    Ну прикинь, у меня в проекте выравнивание - 4 байта, а в твоем - 2 байта. Мне надо использовать твои труды и я решил заинклудить твои поделки. Да я умру ищя ошибки.

    [Ссылки могут видеть только зарегистрированные пользователи. ]

    Вот там все описано.

    А вот пример:
    Код :
    #include <iostream>
    #pragma pack(4) 
     
    struct A {
      int a;
      bool b;
      int c;
    };
     
    int main() {
    	A a;
    	std::cout << (int)&a.a - (int)&a << std::endl
    						<< (int)&a.b - (int)&a << std::endl
    						<< (int)&a.c - (int)&a << std::endl
    						<< sizeof(a) << std::endl;
    }
    /*
    ./main
    0
    4
    8
    12
    */
    Если думаешь что все понял, то еще пример
    Код :
    #include <iostream>
    #pragma pack(4) 
     
    struct A {
      int a;
      bool b;
      bool c[4];
    };
     
    int main() {
    	A a;
    	std::cout << (int)&a.a - (int)&a << std::endl
    						<< (int)&a.b - (int)&a << std::endl
    						<< (int)&a.c - (int)&a << std::endl
    						<< sizeof(a) << std::endl;
    }
     
    /*
    ./main
    0
    4
    5
    12
    */

    Вобщем там есть куча артефактов с битовыми полями (оно там как-то спорно по стандарту вроде как).
    Правило такое общее (с хабры скопипастил)
    В общем выравниваются в памяти поля по границе кратной своему же размеру. То есть 1-байтовые поля не выравниваются, 2-байтовые — выравниваются на чётные позиции, 4-байтовые — на позиции кратные четырём и т.д. В большинстве случаев (или просто предположим что сегодня это так) выравнивание размера структуры в памяти составляет 4 байта
    Ну как видишь массив однобайтовых символов отказался выравниваться (потому что символы однобайтовые), хотя сам массив вроде как стабильно занимал бы в памяти 4 байта и можно было бы предположить что он как и int выравнится по 4 байтам. А нет, надо все это помнить если ченить низкоуровневое ваяешь, но я не ваяю почти.
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  6. #5  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 249 раз(а) в 164 сообщениях
    Если пример не понятен - пиши, нарисую карту как в статье на хабре
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  7. #6  
    Профи Аватар для stabud
    Регистрация
    05.01.2013
    Сообщений
    784
    Сказал(а) спасибо
    326
    Поблагодарили 348 раз(а) в 275 сообщениях
    Записей в блоге
    6
    Я понял, особенно после прочтения хабра. Спасибо.
    Ответить с цитированием  
     

  8. #7  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 249 раз(а) в 164 сообщениях
    Я понял, особенно после прочтения хабра. Спасибо.
    МБ тогда нарисуешь картинку ко второму коду? - занятые байты и свободные.

    К первому я вот нарисовал:
    0 - 3 (int a)
    4 - (bool b)
    5 - 7 (свободно)
    8 - 11 (int c)
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  9. #8  
    Профи Аватар для stabud
    Регистрация
    05.01.2013
    Сообщений
    784
    Сказал(а) спасибо
    326
    Поблагодарили 348 раз(а) в 275 сообщениях
    Записей в блоге
    6
    Для второго примера, я так думаю пустые байты будут в конце. То есть в середине промежутков нет. Хотя по идее должно быть как у первого, но на основе результатов 0,4,5 так не выходит.
    Ответить с цитированием  
     

  10. #9  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 249 раз(а) в 164 сообщениях
    Код :
    struct A {
      int a;
      bool b;
      bool c[4];
    };

    Я думаю так
    0 - 3 (int a)
    4 - (bool b)
    5 - 8 - (bool c[4])
    9 - 11 - (пусто)
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  11. #10  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,935
    Сказал(а) спасибо
    1,845
    Поблагодарили 986 раз(а) в 844 сообщениях
    Записей в блоге
    1
    Вообще выравнивание нужно для определённых оптимизаций выборки и завязано это на работе с памятью.
    Естественно это нужно для структур которые привязаны к большим кускам памяти, процессор не имеет какой-то
    мифической невозможности адресовать однобайтно, поэтому можно смело отрубать эту фичу(и я б её отрубал).
    И голову себе не забивайте этой ереснёй, программирование ради программирования вещь очень смутная.
    Вот если требуется супер оптимизация тогда можно что-то там вертеть крутить и то это надо тестировать всё.
    Был у меня случай, когда выравнивание дало прирост почти в два раза, но это давно было на старом компе и скорее
    всего была особенность видеопамяти того компа. И бошку этим забивать не надо, пусть работает автоматика(
    если уж так нужна эта фича), в ЯП должны быть средства определения смещения в структуре. Но вообще лучше
    самому вручную выравнивать структуру, грамотное распределение битов позволяет экономить память, а чем
    меньше размер прохода по памяти - тем быстрее работает прога.

    выравнивание размера структуры в памяти составляет 4 байта
    Ну да для 32 битных машинок всё так и есть.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •