Котуинко
Re: Котуинко
[uquote="ARV",url="/forum/viewtopic.php?p=3701600#p3701600"]так делать нельзя, потому что компиляр обязательно возмутится многократным объявлением одного и того же "символа" codetable[/uquote]
Const, constexpr и static ограничивают видимость текущим юнитом трансляции, потому все скомпилируется, но в каждом юните будет своя копия массива.
Const, constexpr и static ограничивают видимость текущим юнитом трансляции, потому все скомпилируется, но в каждом юните будет своя копия массива.
- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Котуинко
ок, раз пошла такая пьянка...
main.ctest2.htest.ctest1.hрезультат сборки проектаAVR-GCC 6.3.0
самая свежая версия, которая у меня есть AVR-GCC 8.2.0 - тот же результат
вот это я называю
main.c
Код: Выделить всё
#include <avr/io.h>
#include "test2.h"
int main(void){
while(1){
PORTB;
}
}
Код: Выделить всё
#ifndef TEST2_H_
#define TEST2_H_
char const codetable[8] = {1,2,3,4,5,6,7,8};
#endif /* TEST2_H_ */
Код: Выделить всё
#include <avr/io.h>
#include "test1.h"
Код: Выделить всё
#ifndef TEST1_H_
#define TEST1_H_
char const codetable[8] = {1,2,3,4,5,6,7,8};
#endif /* TEST1_H_ */
Код: Выделить всё
make all
Building file: ../main.c
Invoking: AVR Compiler
avr-gcc -Wall -g2 -gdwarf-2 -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=attiny13 -DF_CPU=8000000UL -MMD -MP -MF"main.d" -MT"main.o" -c -o "main.o" "../main.c"
Finished building: ../main.c
Building file: ../test.c
Invoking: AVR Compiler
avr-gcc -Wall -g2 -gdwarf-2 -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=attiny13 -DF_CPU=8000000UL -MMD -MP -MF"test.d" -MT"test.o" -c -o "test.o" "../test.c"
Finished building: ../test.c
Building target: BULLSHIT.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,BULLSHIT.map -mmcu=attiny13 -o "BULLSHIT.elf" ./main.o ./test.o
./test.o:(.rodata.codetable+0x0): multiple definition of `codetable'
./main.o:(.rodata.codetable+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [BULLSHIT.elf] Error 1самая свежая версия, которая у меня есть AVR-GCC 8.2.0 - тот же результат
вот это я называю
только я совсем не сильно удивлен. жду извинений от тех, кто меня голословно обвинил.jcxz писал(а):хоть что-то написать на си
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Котуинко
[uquote="ARV",url="/forum/viewtopic.php?p=3701684#p3701684"]результат сборки проекта[/uquote]
Мне чтоб получить такой результат для gcc 8.3 пришлось переключиться на С, для С++ все собирается и получается два массива с разными адресами.
Мне чтоб получить такой результат для gcc 8.3 пришлось переключиться на С, для С++ все собирается и получается два массива с разными адресами.
Re: Котуинко
Говоря об отличии программ под АВР я имел ввиду то, что для них применяется "обособленный подход" при работе с размещением данных в области ПЗУ - через PROGMEM (при подключении #include <avr/pgmspace.h> и прочих "мелочах").
В случае с иными МК вступают в силу "общесишные правила". А там как-то специально не указывается, ГДЕ компилятору вздумается разместить данные - в виде отдельной последовательности в области памяти программ или частью команды (относительно числовой константы) или таблицей в ПЗУ с доступом к ее элементам относительно текущей выполняемой команды в теле программного кода.
Насчет ПК...
Там действует модель совмещенной памяти программ-данных с подкачкой из жесткого диска (силами операционной системы) в случае, когда программа имеет средства доступа к накопителям (жесткий диск, флеш-накопители и подобное).
У МК таких практически не встречается.
Разве что у АРМ совмещенное ОЗУ с правом выполнения кода программы из его области - но то больше уж кристаллы для профприменений (и то не всякие), да MCS51 в режиме микропроцессора (на данный момент практически нигде не вспоминающемся).

И относительно адуриньи...
Там таки не С, а С++ (да еще и в каком-то гибридном симбиозе) - посему могут иметь место разнообразные "НЮЁНСЫ"...

В случае с иными МК вступают в силу "общесишные правила". А там как-то специально не указывается, ГДЕ компилятору вздумается разместить данные - в виде отдельной последовательности в области памяти программ или частью команды (относительно числовой константы) или таблицей в ПЗУ с доступом к ее элементам относительно текущей выполняемой команды в теле программного кода.
Насчет ПК...
Там действует модель совмещенной памяти программ-данных с подкачкой из жесткого диска (силами операционной системы) в случае, когда программа имеет средства доступа к накопителям (жесткий диск, флеш-накопители и подобное).
У МК таких практически не встречается.
Разве что у АРМ совмещенное ОЗУ с правом выполнения кода программы из его области - но то больше уж кристаллы для профприменений (и то не всякие), да MCS51 в режиме микропроцессора (на данный момент практически нигде не вспоминающемся).
И относительно адуриньи...
Там таки не С, а С++ (да еще и в каком-то гибридном симбиозе) - посему могут иметь место разнообразные "НЮЁНСЫ"...
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Котуинко
У IAR для AVR прикольно сделано с размещением данных. И дальше с ними можно работать особо не парясь где они находятся. Есть некоторые тонкости, но в доках это хорошо расписано.
Код: Выделить всё
const int var; // В RAM
__flash const int var; // Во FLASH
__eeprom const int var; // Константа в EEPROM
__eeprom int var; // Переменная в EEPROM- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Котуинко
так я о Си и вел речь. и jcxz тоже о Си.Reflector писал(а):Мне чтоб получить такой результат для gcc 8.3 пришлось переключиться на С
в плюсах я не копенгаген и в основном молчу в тряпочку.
начиная с AVR-GCC 4.x.x почти так же сделаноVladislavS писал(а):У IAR для AVR прикольно сделано
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Котуинко
Имеет смысл переключить компилятор в режим С++ раз и навсегда, даже если не пользуешься всеми плюсами плюсов.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Котуинко
зачем? чтобы в очередной раз попасть на "нюансик"? Если уж пишешь на Си, то и не стоит портить себе карму режимом С++. Ну и наоборот.VladislavS писал(а):Имеет смысл переключить компилятор в режим С++ раз и навсегда
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Котуинко
[uquote="Reflector",url="/forum/viewtopic.php?p=3701665#p3701665"]Const, constexpr и static ограничивают видимость текущим юнитом трансляции, потому все скомпилируется, но в каждом юните будет своя копия массива.[/uquote]
Приведите код того исходника из которого получается 2 экземпляра.
Добавлено after 2 minutes 22 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3701709#p3701709"]Мне чтоб получить такой результат для gcc 8.3 пришлось переключиться на С, для С++ все собирается и получается два массива с разными адресами.[/uquote]
*.h-файл: static u64 const tPow10[] = {...};
.map-файл: tPow10 0xd00002c0 0xa0 Data Lc ui.o [2] - один единственный во всём .map.
IAR for ARM.
Добавлено after 5 minutes 9 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3701748#p3701748"]так я о Си и вел речь. и jcxz тоже о Си.[/uquote]
Какой смысл использовать чистый си в наше время? Не понимаю совершенно. Это то же самое, что использовать каменный топор. Последние 20 лет использую только .cpp.
Добавлено after 3 minutes 1 second:
[uquote="ARV",url="/forum/viewtopic.php?p=3701767#p3701767"]зачем? чтобы в очередной раз попасть на "нюансик"? Если уж пишешь на Си, то и не стоит портить себе карму режимом С++. Ну и наоборот.[/uquote]
Затем чтобы не чертыхаться потом, когда придётся компилить что-то например под MFC (win). И не наступать на грабли из-за наличия и си и си++ файлов.
Даже для .c-файлов всегда включаю режим компиляции си++. Не думал что кто-то ещё настолько отстал от жизни...
Добавлено after 6 minutes 14 seconds:
[uquote="BOB51",url="/forum/viewtopic.php?p=3701717#p3701717"]Разве что у АРМ совмещенное ОЗУ с правом выполнения кода программы из его области - но то больше уж кристаллы для профприменений (и то не всякие), да MCS51 в режиме микропроцессора (на данный момент практически нигде не вспоминающемся).[/uquote]
Полно и микроконтроллеров с одним только ОЗУ: LPC43xx, ESP8266, ESP32, CY68013A (ядро как раз x8051 и используется сейчас широко - в тех же дешёвых лог.анализаторах например), сигнальники всякие и т.д.
Приведите код того исходника из которого получается 2 экземпляра.
Добавлено after 2 minutes 22 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3701709#p3701709"]Мне чтоб получить такой результат для gcc 8.3 пришлось переключиться на С, для С++ все собирается и получается два массива с разными адресами.[/uquote]
*.h-файл: static u64 const tPow10[] = {...};
.map-файл: tPow10 0xd00002c0 0xa0 Data Lc ui.o [2] - один единственный во всём .map.
IAR for ARM.
Добавлено after 5 minutes 9 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3701748#p3701748"]так я о Си и вел речь. и jcxz тоже о Си.[/uquote]
Какой смысл использовать чистый си в наше время? Не понимаю совершенно. Это то же самое, что использовать каменный топор. Последние 20 лет использую только .cpp.
Добавлено after 3 minutes 1 second:
[uquote="ARV",url="/forum/viewtopic.php?p=3701767#p3701767"]зачем? чтобы в очередной раз попасть на "нюансик"? Если уж пишешь на Си, то и не стоит портить себе карму режимом С++. Ну и наоборот.[/uquote]
Затем чтобы не чертыхаться потом, когда придётся компилить что-то например под MFC (win). И не наступать на грабли из-за наличия и си и си++ файлов.
Даже для .c-файлов всегда включаю режим компиляции си++. Не думал что кто-то ещё настолько отстал от жизни...
Добавлено after 6 minutes 14 seconds:
[uquote="BOB51",url="/forum/viewtopic.php?p=3701717#p3701717"]Разве что у АРМ совмещенное ОЗУ с правом выполнения кода программы из его области - но то больше уж кристаллы для профприменений (и то не всякие), да MCS51 в режиме микропроцессора (на данный момент практически нигде не вспоминающемся).[/uquote]
Полно и микроконтроллеров с одним только ОЗУ: LPC43xx, ESP8266, ESP32, CY68013A (ядро как раз x8051 и используется сейчас широко - в тех же дешёвых лог.анализаторах например), сигнальники всякие и т.д.
Re: Котуинко
[uquote="jcxz",url="/forum/viewtopic.php?p=3701776#p3701776"]*.h-файл: static u64 const tPow10[] = {...};
.map-файл: tPow10 0xd00002c0 0xa0 Data Lc ui.o [2] - один единственный во всём .map.
IAR for ARM.[/uquote]
Проверил еще на MSVC:
.map-файл: tPow10 0xd00002c0 0xa0 Data Lc ui.o [2] - один единственный во всём .map.
IAR for ARM.[/uquote]
Проверил еще на MSVC:
Код: Выделить всё
0003:00000b30 ?codetable@@3QBDB 00419b30 ConsoleApplication.obj
0003:00000b40 ?codetable@@3QBDB 00419b40 test1.objRe: Котуинко
[uquote="jcxz",url="/forum/viewtopic.php?p=3701776#p3701776"]Какой смысл использовать чистый си в наше время? Не понимаю совершенно. Это то же самое, что использовать каменный топор. Последние 20 лет использую только .cpp[/uquote]даже сейчас далеко не подо все есть компиляторы C++. Любопытно, чем это таким вы 20 лет назад компиляли плюсовый код для контроллеров.
Re: Котуинко
[uquote="Reflector",url="/forum/viewtopic.php?p=3701794#p3701794"]Проверил еще на MSVC:
[/uquote]
А размер/содержимое совпадают? А то может там только адрес этого массива лежит
Может где-то галку поставить надо, чтобы не дублировал? Я в IAR ничего не делал - он изначально вроде не дублирует.
Код: Выделить всё
0003:00000b30 ?codetable@@3QBDB 00419b30 ConsoleApplication.obj
0003:00000b40 ?codetable@@3QBDB 00419b40 test1.objА размер/содержимое совпадают? А то может там только адрес этого массива лежит
Может где-то галку поставить надо, чтобы не дублировал? Я в IAR ничего не делал - он изначально вроде не дублирует.
Re: Котуинко
Применение ядра mcs51 и использование режима микропроцессора не одно и то же.
Посмотрите хотя бы проект КОТУИНКО с которого собственно и начиналась эта ветка.
Там как раз классика с внешней памятью программ/данных да проект полностью под ассемблером.
А вот сейчас я по крохам собираю истину относительно работ с Ардино подобными в рамках средств, предоставленных ардуиноIDE. Приходится и Си и С++ пересматривать...
Да все вычитанное перепроверять.
Так что спасибо всем, кто информацию для размышления подбрасывает!
По мере возможностей измышляю тест-проекты для перепроверки полученной информации.
А сие дело тяжкое - самому придумывать...
В то же время "чужих" проектов с адуриньей да с минимумом "чужих" библиотек (из наборов спец сопровождения платформ IDE) не так много попадается для анализа.
Изучение состава профбиблиотек дело весьма накладное - уровень их разработок и "разношерстность" не дают чётко выясняемых ответов при конкретных тестах - не мой уровень в них лазить пока...
Да и обычная практика адуринщиков - не рисовать принципиальных схем воспринимается весьма противошерстно. Адуринка весьма неплохо и в виде микросборки рисуется - надо таки кусманчик совести иметь и схемки рисовать!

Пока идёт обработка уже полученной инфы, да размышления с просмотром чужих сообщений.

Посмотрите хотя бы проект КОТУИНКО с которого собственно и начиналась эта ветка.
Там как раз классика с внешней памятью программ/данных да проект полностью под ассемблером.
А вот сейчас я по крохам собираю истину относительно работ с Ардино подобными в рамках средств, предоставленных ардуиноIDE. Приходится и Си и С++ пересматривать...
Да все вычитанное перепроверять.
Так что спасибо всем, кто информацию для размышления подбрасывает!
По мере возможностей измышляю тест-проекты для перепроверки полученной информации.
А сие дело тяжкое - самому придумывать...
В то же время "чужих" проектов с адуриньей да с минимумом "чужих" библиотек (из наборов спец сопровождения платформ IDE) не так много попадается для анализа.
Изучение состава профбиблиотек дело весьма накладное - уровень их разработок и "разношерстность" не дают чётко выясняемых ответов при конкретных тестах - не мой уровень в них лазить пока...
Да и обычная практика адуринщиков - не рисовать принципиальных схем воспринимается весьма противошерстно. Адуринка весьма неплохо и в виде микросборки рисуется - надо таки кусманчик совести иметь и схемки рисовать!
Пока идёт обработка уже полученной инфы, да размышления с просмотром чужих сообщений.
Re: Котуинко
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3701801#p3701801"]даже сейчас далеко не подо все есть компиляторы C++. Любопытно, чем это таким вы 20 лет назад компиляли плюсовый код для контроллеров.[/uquote]
Ну так под то, под что есть - почему не использовать? Классы ведь никто не заставляет писать.
А под что сейчас нет си++? Наверное какой-то раритет?
20 лет назад не для МК, а для ПК. 20 лет назад под МК я только на асме писал
Ну так под то, под что есть - почему не использовать? Классы ведь никто не заставляет писать.
А под что сейчас нет си++? Наверное какой-то раритет?
20 лет назад не для МК, а для ПК. 20 лет назад под МК я только на асме писал
Re: Котуинко
я, честно говоря, тоже быстро запутался, что там у вас где и как "включено" или "входит в состав")
[uquote="BOB51",url="/forum/viewtopic.php?p=3701477#p3701477"]Вот тут и всплывает extern...
А описания по ее применению таки совсем маловато... Относительно простых для восприятия...[/uquote]их мало потому, что extern насамделе очень простая вещь
это описание переменной, а не ее объявление - вот ровно то же самое, что прототипы функций.
[uquote="BOB51",url="/forum/viewtopic.php?p=3701477#p3701477"]Вот тут и всплывает extern...
А описания по ее применению таки совсем маловато... Относительно простых для восприятия...[/uquote]их мало потому, что extern насамделе очень простая вещь
Re: Котуинко
[uquote="jcxz",url="/forum/viewtopic.php?p=3701804#p3701804"]А размер/содержимое совпадают? А то может там только адрес этого массива лежит 
Может где-то галку поставить надо, чтобы не дублировал? Я в IAR ничего не делал - он изначально вроде не дублирует.[/uquote]
Все совпадает, даже с максимальной оптимизацией получается два одинаковых массива, не важно const в объявлении, static или static const... Добавляешь inline или объявляешь с extern и определяешь отдельно, тогда остается один массив. Так и должно быть, потому и ошибки нет, что эти массивы друг друга не видят.
Может где-то галку поставить надо, чтобы не дублировал? Я в IAR ничего не делал - он изначально вроде не дублирует.[/uquote]
Все совпадает, даже с максимальной оптимизацией получается два одинаковых массива, не важно const в объявлении, static или static const... Добавляешь inline или объявляешь с extern и определяешь отдельно, тогда остается один массив. Так и должно быть, потому и ошибки нет, что эти массивы друг друга не видят.
Re: Котуинко
[uquote="Reflector",url="/forum/viewtopic.php?p=3701818#p3701818"]Все совпадает, даже с максимальной оптимизацией получается два одинаковых массива, не важно const в объявлении, static или static const... Добавляешь inline или объявляешь с extern и определяешь отдельно, тогда остается один массив. Так и должно быть, потому и ошибки нет, что эти массивы друг друга не видят.[/uquote]
Проверил - да VS_2017 молча создаёт два экземпляра. VS_2005 - не показывает ни одного экземпляра в .map (под отладчиком проверять некогда).
А вот IAR всегда создаёт только один экземпляр. Просмотрел все опции проекта - не нашёл такой, которая на это влияет. Есть "Merge duplicate sections", но она на это не влияет.
Добавлено after 1 minute 10 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3701818#p3701818"]Так и должно быть, потому и ошибки нет, что эти массивы друг друга не видят.[/uquote]
Почему "должно быть"? Имхо - должен быть как раз один экземпляр. Раз это const, то какой смысл его дублировать?
Проверил - да VS_2017 молча создаёт два экземпляра. VS_2005 - не показывает ни одного экземпляра в .map (под отладчиком проверять некогда).
А вот IAR всегда создаёт только один экземпляр. Просмотрел все опции проекта - не нашёл такой, которая на это влияет. Есть "Merge duplicate sections", но она на это не влияет.
Добавлено after 1 minute 10 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3701818#p3701818"]Так и должно быть, потому и ошибки нет, что эти массивы друг друга не видят.[/uquote]
Почему "должно быть"? Имхо - должен быть как раз один экземпляр. Раз это const, то какой смысл его дублировать?
Re: Котуинко
[uquote="jcxz",url="/forum/viewtopic.php?p=3701836#p3701836"]Почему "должно быть"? Имхо - должен быть как раз один экземпляр. Раз это const, то какой смысл его дублировать?[/uquote]
После того как все заинклудится останется два .cpp файла в каждом из которых будет определение для массива:
Стандарт С++ говорит, что у константных объектов внутренняя линковка(для С она внешняя), потому такой код компилируется и в каждой единице трансляции будет по независимому экземпляру массива. Смысла в этом может и не быть, только это уже задача оптимизатора определять такие вещи, причем поскольку массивы будут в разных юнитах трансляции, то как минимум нужен какой-нибудь LTO и я не уверен, что он в принципе будет что-то делать с объектами для которых задана внутренняя линковка. Но такая оптимизация вполне возможна и видимо IAR ее в определенных случаях делает, но при этом сам код нельзя назвать правильным, т.к. он не обязательно делает то, что от него ожидается. Если это ПК и доступен С++17, то тут однозначно нужно добавлять inline:
Если мк и хочется избежать лишней проверки, то нужен extern и тогда будет один массив всегда и везде 
После того как все заинклудится останется два .cpp файла в каждом из которых будет определение для массива:
Код: Выделить всё
// test1.cpp
char const codetable[8] = {1,2,3,4,5,6,7,8};
// test2.cpp
char const codetable[8] = {1,2,3,4,5,6,7,8};Код: Выделить всё
// test.h
inline char const codetable[8] = {1,2,3,4,5,6,7,8};Re: Котуинко
УПСь...
А что за зверь такой - LTO?
как-то вкратце и для неведающих...
Ибо таки встречается в настройках платформ "сторонних производителей"
DIY......by James Sleeman
..... by MCUdude
к примеру... стоит флажок "вкл/откл" ... иногда матюкается при попытке смены статуса "по умолчанию"...

А что за зверь такой - LTO?
как-то вкратце и для неведающих...
Ибо таки встречается в настройках платформ "сторонних производителей"
DIY......by James Sleeman
..... by MCUdude
к примеру... стоит флажок "вкл/откл" ... иногда матюкается при попытке смены статуса "по умолчанию"...
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Котуинко
LTO = Link Time Optimization, оптимизация на этапе линковки. я понял эту оптимизацию примерно так: поскольку линкер склеивает отдельные модули скомпилированного кода, он может находить куски, общие для разных объектных файлов. например, в одном модуле есть функция, которая почти совпадает по логике работы с функцией в другом модуле, и отличается буквально в мелочах. так вот, при LTO вместо двух кусков кода для почти одинаковых функций остается только один кусок с общей частью и небольшие добавки, обеспечивающие "разницу". в итоге может получиться заметный эффект уменьшения объема, но при этом "символьная" отладка становится практически невозможной, т.к. теряется связь участков машинных команд не только с конкретными строками исходника (что для любой оптимизации характерно), но и даже с модулями, т.е. с исходными файлами в принципе.
для AVR-GCC LTO еще не сильно хороша - в некоторых версиях она работает, в некоторых нет. но если работает, то "без усилий" дает от 200 байт до 5-6% выигрыша в размере кода - очень сильно зависит от объема проекта и множества неизвестных мне факторов...
для AVR-GCC LTO еще не сильно хороша - в некоторых версиях она работает, в некоторых нет. но если работает, то "без усилий" дает от 200 байт до 5-6% выигрыша в размере кода - очень сильно зависит от объема проекта и множества неизвестных мне факторов...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


