Днес се натъкнах на една особеност, която, макар и не особено важна, все пак ме озадачи. Може би и аз просто не разбирам C++ правилно.
Някои масиви в изходен файл сочат към низови литерали, като така:
const char* a[] = { "a", "b", "c" };
const char* b[] = { "d", "e"};
const char* c[] = { "f", "g"};
Нито един от тези масиви с указатели никога не се използва по никакъв начин, освен да бъде предаден на GetProcAddress
за извличане на функционален указател от библиотека (това е неблокиращ динамичен OpenAL/EFX/зареждащ функция за зареждане и създател/мениджър на контекст).
В крайна сметка ми хрумна, че вероятно трябва да декларирам тези променливи като static const
, тъй като те не са необходими никъде извън този .cpp файл, така че изричното вътрешно свързване изглеждаше подходящо. Те така или иначе трябва да имат вътрешна връзка (ISO14882 3.5(3)), така че ние сме само добри граждани, като изрично посочваме това, което компилаторът вече приема.
Извършването на тази невинна промяна доведе до увеличаване на размера на изпълнимия файл с 512 байта. Не като допълнителен 512b наистина има значение, но просто не изглеждаше логично точно същото нещо да доведе до различен код. Тъй като static const
е отхвърлен (ISO14882 7.3.1.1(2)), опитах и анонимно пространство от имена със същия резултат.
Разглеждането на изходния код на асемблера показва, че изричното вътрешно свързване (static
или namespace{}
) ще премести низовите литерали в .rdata
, а не в .data
, а низовите литерали се преплитат с масиви от указател към низов литерал, вместо да имат всички низове и всички указатели в един блок, респ. Тук вероятно се крие и причината за различния размер - много вероятно разместването на данни от една секция в друга е достигнало ограничение за размера на секцията. Интересното е, че и трите вкуса променят имената по различен начин.
Сега се чудя: Правя ли грешка, трябва ли тези указатели да не имат вътрешна връзка?
Освен това според моето разбиране const
вече е само за четене, доколко static const
е "повече само за четене" (едното влиза в .rdata
, а другото не)?