Какие ограничения на имена идентификаторов накладывает компоновщик gnu ld?
В документации я про это ничего не нашел.
gcc не накладывает ограничений на локальные переменные, а вот ограничения на внешние переменные вроде определяются компоновщиком.
Ограничение на размер идентификаторов в gnu ld
Модератор: Модераторы разделов
-
savigm
- Сообщения: 127
- ОС: openSUSE
-
savigm
- Сообщения: 127
- ОС: openSUSE
Re: Ограничение на размер идентификаторов в gnu ld
Эксперементировал с большими(около 100 символов) внешними именами, но ограничений так и не выявил. Скорее всего их просто нет в gnu ld.
Вопрос у меня изначально возник по причине чтения всем известной книги Бьерна Страуструпа "С++, язык программирования". В 4 главе наткнулся на простейшее упражнение (сложность 1 из 5 по книге):
Тут я сел. Документация по gcc гласит:
Т.е. локальные имена не ограничены по длине, а вот внешние определяются ограничениями компоновщика gnu ld. В документации по gnu ld я ничего по этому поводу не нашел. Т.е. такое простейшее упражнение, во всем известной книге, а мне с 3-х форумов пока ответов так и не дали, да и я потратил немало времени на выяснение ответа, и толком так его и не получил, только результат эксперемента.
Вопрос у меня изначально возник по причине чтения всем известной книги Бьерна Страуструпа "С++, язык программирования". В 4 главе наткнулся на простейшее упражнение (сложность 1 из 5 по книге):
Какой максимальной длины может быть внешнее имя в вашей системе?
Тут я сел. Документация по gcc гласит:
For internal names, all characters are significant. For external names, the number of significant characters are defined by the linker; for almost all targets, all characters are significant.
Т.е. локальные имена не ограничены по длине, а вот внешние определяются ограничениями компоновщика gnu ld. В документации по gnu ld я ничего по этому поводу не нашел. Т.е. такое простейшее упражнение, во всем известной книге, а мне с 3-х форумов пока ответов так и не дали, да и я потратил немало времени на выяснение ответа, и толком так его и не получил, только результат эксперемента.
-
savigm
- Сообщения: 127
- ОС: openSUSE
Re: Ограничение на размер идентификаторов в gnu ld
Нашел книженцию по ссылке самого Бьерна Страуструпа на книжку:
C++ Solutions: Companion to the C++ Programming Language (3rd Edition) By David Vandevoorde, Bjarne Stroustrup
В ней решены большинство примеров, есть исходники в свободном доступе.
Так вот: ответ на то упражнение оказывается и рассчитан на эксперементальную программулину с длинным именем.
Вот иходник решения:
Общий смысл я понял, но детали как все это работает мне непонятны, если кто пояснит, буду признателен.
Хотя в тексте черным по белому сказано: в первую очередь смотрите ответ на вопрос в документации по компилятору и компоновщику, вот здесь-то и косяк - в доках по компоновщику gnu ld про это ни слова.
Вообще решения довольно непростые для таких несложных глав.
C++ Solutions: Companion to the C++ Programming Language (3rd Edition) By David Vandevoorde, Bjarne Stroustrup
В ней решены большинство примеров, есть исходники в свободном доступе.
Так вот: ответ на то упражнение оказывается и рассчитан на эксперементальную программулину с длинным именем.
Вот иходник решения:
Код: Выделить всё
/* Code for exercise 4.6.
|
| "C++ Solutions--Companion to The C++ Programming Language, Third Edition"
| by David Vandevoorde; Addison-Wesley 1998; ISBN 0-201-30965-3.
|
| Permission to use, copy, modify, distribute and sell this software
| and its documentation for any purpose is hereby granted without fee.
| The author makes no representations about the suitability of this
| software for any purpose. It is provided "as is" without express or
| implied warranty.
`----------------------------------------------------------------------*/
/*
This file may cause all sorts of problems for various compilers and
associated tools. Here is one message of a compiler that attempted
processing of this file. It speaks for itself:
External symbol too long, truncated from 14328 to 4000 bytes,
f__FP8DoublifyXT8DoublifyXT8DoublifyXT8DoublifyXT8DoublifyXT8DoublifyXT8Dou
blifyXT8DoublifyXT8DoublifyXT8DoublifyXTdTd_T8Doublif...
*/
template<typename T, typename U>
struct Doublify {};
template<int N>
struct Exponential {
typedef Doublify<typename Exponential<N-1>::LongType,
typename Exponential<N-1>::LongType>
LongType;
};
template<>
struct Exponential<0> {
typedef double LongType;
};
int f(Exponential<10>::LongType*) {
return 3;
}Общий смысл я понял, но детали как все это работает мне непонятны, если кто пояснит, буду признателен.
Хотя в тексте черным по белому сказано: в первую очередь смотрите ответ на вопрос в документации по компилятору и компоновщику, вот здесь-то и косяк - в доках по компоновщику gnu ld про это ни слова.
Вообще решения довольно непростые для таких несложных глав.
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Ограничение на размер идентификаторов в gnu ld
Ну, рассмотрим Exponential<3>::LongType:
Exponential<3> - N == 0 ? нет, значит берем стандартное описание
struct Exponential<3> { typedef Doublify<typename Exponential<2>::LongType, typename Exponential<2>::LongType> LongType; }::LongType;
Exponential<2> - N == 0 ? нет, берем стандартное описание
struct Exponential<3> { typedef Doublify<typename struct Exponential<2> { typedef Doublify<typename Exponential<1>::LongType, typename Exponential<1>::LongType> LongType; }::LongType, typename struct Exponential<2> { typedef Doublify<typename Exponential<1>::LongType, typename Exponential<1>::LongType> LongType; }::LongType> LongType; }::LongType;
Exponential<1> - N == 0 ? нет, берем стандартное описание
struct Exponential<3> { typedef Doublify<typename struct Exponential<2> { typedef Doublify<typename struct Exponential<1> { typedef Doublify<typename Exponential<0>::LongType, typename Exponential<0>::LongType> LongType; }::LongType, typename struct Exponential<1> { typedef Doublify<typename Exponential<0>::LongType, typename Exponential<0>::LongType> LongType; }::LongType> LongType; }::LongType, typename struct Exponential<2> { typedef Doublify<typename struct Exponential<1> { typedef Doublify<typename Exponential<0>::LongType, typename Exponential<0>::LongType> LongType; }::LongType, typename struct Exponential<1> { typedef Doublify<typename Exponential<0>::LongType, typename Exponential<0>::LongType> LongType; }::LongType> LongType; }::LongType> LongType; }::LongType;
Exponential<0> - N == 0 ? да, теперь берем второе описание для конкретного числа
struct Exponential<3> { typedef Doublify<typename struct Exponential<2> { typedef Doublify<typename struct Exponential<1> { typedef Doublify<typename struct Exponential<0> { typedef double LongType;}::LongType, typename struct Exponential<0> { typedef double LongType;}::LongType> LongType; }::LongType, typename struct Exponential<1> { typedef Doublify<typename struct Exponential<0> { typedef double LongType;}::LongType, typename struct Exponential<0> { typedef double LongType;}::LongType> LongType; }::LongType> LongType; }::LongType, typename struct Exponential<2> { typedef Doublify<typename struct Exponential<1> { typedef Doublify<typename struct Exponential<0> { typedef double LongType;}::LongType, typename struct Exponential<0> { typedef double LongType;}::LongType> LongType; }::LongType, typename struct Exponential<1> { typedef Doublify<typename struct Exponential<0> { typedef double LongType;}::LongType, typename struct Exponential<0> { typedef double LongType;}::LongType> LongType; }::LongType> LongType; }::LongType> LongType; }::LongType;
Ну, и подстановка конкретных значений:
Exponential<3>::LongType == Doublify<Doublify<Doublify<double, double>, Doublify<double, double> >, Doublify<Doublify<double, double>, Doublify<double, double> > >
Вот так. Ну, а для 10 - 1024 будет только double... что дает очень немаленькое имя типа
-
savigm
- Сообщения: 127
- ОС: openSUSE
Re: Ограничение на размер идентификаторов в gnu ld
NickLion, Спасибо конечно, но я почти ничего не понял, можно в двух словах, что делается?
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Ограничение на размер идентификаторов в gnu ld
Не, в двух словах не получится...
Exponential объявлено в двух ипостасях - для произвольного целого значения N и для целого 0.
Для 0 определено как структура, содержащая описание типа LongType == double.
Для произвольного N тип с таким же именем объявлен как Doublify< тип LongType для Exponential с N-1, тип LongType для Exponential с N-1 >.
Т.е. получается рекурсия типа Doublify, причем получается 2 в степени N.
Так понятнее?
Exponential объявлено в двух ипостасях - для произвольного целого значения N и для целого 0.
Для 0 определено как структура, содержащая описание типа LongType == double.
Для произвольного N тип с таким же именем объявлен как Doublify< тип LongType для Exponential с N-1, тип LongType для Exponential с N-1 >.
Т.е. получается рекурсия типа Doublify, причем получается 2 в степени N.
Так понятнее?