Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> sizeof времени компиляции 
V
    Опции темы
fry
Дата 19.11.2009, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Всем привет. Потребовалось написать метапрограмку и стопорнулся на ровном месте. Суть: необходимо вычислить выражение sizeof("/какая-либо строка/").
Проблема возникает в том, что выражение-то вычисляется правильно, но та самая "/какая-либо строка/" присутствует в коде программы, а факт ее отсутствия является целью написания. Пробовал заменить выражение на константу - все ОК. Т.е. дело именно в sizeof.
Пишу для GCC из под Linux'а.
Так вот и возникает вопрос: что с этим можно сделать чтобы и вычисление длины проходило и строка в программе не присутствовала.

PS Может есть что другое, что работает схожим с sizeof образом?

Заранее благодарю.
PM MAIL   Вверх
andrew_121
Дата 19.11.2009, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Для строк есть strlen(const char*)


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
fry
Дата 19.11.2009, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



она заменяется на константу во время компиляции?
Мне нельзя использовать переменные.

Это сообщение отредактировал(а) fry - 19.11.2009, 00:57
PM MAIL   Вверх
Alexeis
Дата 19.11.2009, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



fry, тут есть небольшие сложности в определении. Размер строки или ее длинна. Для строк char* длинна всегда меньше ее размера, поскольку не учитывает последний ноль. Но на самом деле размер может быть гораздо больше длинны, поскольку длинна определяется завершающим нулем, а он необязательно в конце выделенного участка памяти. Реальный размер буфера памяти знает только компилятор. Если указатель на строку совпадает с указателем на выделенную память (что не факт) и если строка выделена в куче, то размер выделенной памяти храниться примерно в -8мом байте (размер 4 байта), но это не стандартизировано и зависит от компилятора, так что на это неверно рассчитывать. Правильнее было бы использовать строки STL, для которых всегда известен и размердлина (size) и размер выделенной памяти (capacity).

Добавлено через 3 минуты и 55 секунд
Цитата(fry @  18.11.2009,  23:55 Найти цитируемый пост)
Мне нельзя использовать переменные.

А как же 
Цитата(fry @  18.11.2009,  23:08 Найти цитируемый пост)
вычисление длины проходило и строка в программе не присутствовала.

  Если строка не присутствует, то она переменная. Переменная не имеет фиксированного значения, поэтому ее размер нельзя знать на этапе компиляции.

Это сообщение отредактировал(а) Alexeis - 19.11.2009, 00:58


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
fry
Дата 19.11.2009, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Интересует именно количество значимых символов (до завершающего нуля). Строка должна быть соптимизированна до результата, т.е. вместо этого выражения должна остаться константа, при этом самой строки в программе существовать не должно.
Общая концепция здесь.

Это сообщение отредактировал(а) fry - 19.11.2009, 01:12
PM MAIL   Вверх
fry
Дата 19.11.2009, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Цитата

Правильнее было бы использовать строки STL


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

Это сообщение отредактировал(а) fry - 19.11.2009, 01:58
PM MAIL   Вверх
fry
Дата 19.11.2009, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Пока пришло в голову только такое
Код

template <typename T>
T myTypeOf(T);

#define mySizeOf(Obj) sizeof(myTypeOf(Obj))


С одной стороны работает, с другой нет. Дело в том, что провоцируя ошибку таким образом
Код

template <typename T>
T myTypeOf(T&);

компилятор сообщает, что не может найти подходящего вызова для const char[xxx], что подтверждает итак понятное.
Однако, sizeof возвращаемого значения первого приведенного мной варианта (без ошибки) выводит одно и тоже- 4.
Такое впечатление, что возвращается ссылка на тот самый const char[xxx].
PM MAIL   Вверх
xvr
Дата 19.11.2009, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(fry @ 19.11.2009,  00:08)
Всем привет. Потребовалось написать метапрограмку и стопорнулся на ровном месте. Суть: необходимо вычислить выражение sizeof("/какая-либо строка/").
Проблема возникает в том, что выражение-то вычисляется правильно, но та самая "/какая-либо строка/" присутствует в коде программы, а факт ее отсутствия является целью написания. Пробовал заменить выражение на константу - все ОК. Т.е. дело именно в sizeof.
Пишу для GCC из под Linux'а.

Ничего не путаете?
Код

int p()
{
 return sizeof("Blablabla");
}
результат
Код

    .file    "szof.cpp"
    .text
    .align 2
.globl _Z1pv
    .type    _Z1pv, @function
_Z1pv:
.LFB2:
    pushl    %ebp
.LCFI0:
    movl    %esp, %ebp
.LCFI1:
    movl    $10, %eax
    leave
    ret
.LFE2:
    .size    _Z1pv, .-_Z1pv
    .section    .note.GNU-stack,"",@progbits
    .ident    "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-3)"
как видите, никаких строк нету.

Цитата

Пока пришло в голову только такое
...
Такое впечатление, что возвращается ссылка на тот самый const char[xxx].
Возвращается char*, sizeof чего вам и выдают (4)

PM MAIL   Вверх
bsa
Дата 19.11.2009, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



fry, определить размер строки на этапе компиляции можно так:
Код
template<typename Char,size_t num>
void func(const Char (&v)[num])
{
   //в данном месте num будет размерность массива
}

PM   Вверх
fry
Дата 19.11.2009, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Это кусок кода или весь? Подозреваю, что кусок т.к. у меня код существенно больше и присутствует код перед функцией main. Неважно, будем думать. Пес его знает как он оптимизирует. У меня этот sizeof был как параметр шаблона может это на что влияет, хотя врядли.
PM MAIL   Вверх
xvr
Дата 19.11.2009, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(fry @ 19.11.2009,  17:00)
Это кусок кода или весь? Подозреваю, что кусок т.к. у меня код существенно больше и присутствует код перед функцией main. 

Если это вопрос ко мне - то весь
Цитата

Неважно, будем думать. Пес его знает как он оптимизирует. У меня этот sizeof был как параметр шаблона может это на что влияет, хотя врядли.
В чистом виде строка в sizeof не должна попасть в код, вообще. Видимо она была не только в sizeof  smile 
Можно кусок кода, где это было?

PM MAIL   Вверх
fry
Дата 20.11.2009, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Всем спасибо за ответы.

Цитата

В чистом виде строка в sizeof не должна попасть в код, вообще. Видимо она была не только в sizeof.

С таким выводом не поспоришь, ведь если есть интерес к длине строки, то ее содержание как видимо также небезинтересно.  smile 

Цитата

bsa,
Код

template<typename Char,size_t num>
void func(const Char (&v)[num])
{
   //в данном месте num будет размерность массива
}



Спасибо за подсказку.
Уже пробовал, только реализовывал в классе. Эффект ноль.

Думаю вся проблема в присутствии указателей (константных) при передаче строки как параметра метода. Только вот перепробовав туеву хучу различных вариантов могу сказать, что компилятору в некоторых из них не помешало избавиться от нее в коде программы.

Есть идея передавать как boost::mpl::string, но синтаксис у них отвратительный в плане передачи больших строк. Или я чего-то недопонял.
Хотелось бы передать строку большого размера и обрабатывать ее таким образом, чтобы компилятор ее не вносил в код программы, т.к. сама по себе она не нужна.
PM MAIL   Вверх
Леопольд
Дата 20.11.2009, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(fry @  19.11.2009,  00:08 Найти цитируемый пост)
стопорнулся на ровном месте. Суть: необходимо вычислить выражение sizeof("/какая-либо строка/").

"Доделал" пример bsa
Код

#include <iostream>

template<int size>
struct Length{
    char length[size];
};

template<typename C, int size>
Length<size> StaticLenght(const C (&)[size]);

int main(){
    std::cout<<sizeof(StaticLenght("string"))<<std::endl;
}



Это сообщение отредактировал(а) Леопольд - 20.11.2009, 18:42


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
fry
Дата 20.11.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Цитата

"Доделал" пример bsa

Спасибо за код.
В принципе, я уже проделывал похожий вариант, но, как и этот, он ни к чему ни привел. Думаю я просто поспешил с выводом насчет виновности sizeof.

Есть ли вообще варианты реализации подобия бустовского хранения строк из mpl с нормальной поддержкой строк большой длины. Просто, как я понял, он работает с ними с гарантией работы только во время компиляции, что для меня как раз принципиально важно.
PM MAIL   Вверх
mes
Дата 20.11.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Леопольд @  20.11.2009,  17:39 Найти цитируемый пост)
template<int size>
struct Length{
    char length[size];
};

мне кажется логичнее внутри структуры объявить енум вместо массива и тогда вместо sizeof(StaticLength...) будет StaticLength.value.
 smile 


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0616 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.