Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.06.2012, 11:48   #11
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от asmars Посмотреть сообщение
хм..
а если вместо sizeof поставить strlen ?
Я тут многабукав написал. Если вкратце: лучше не уповать на компиль, а такие моменты самостоятельно выносить за пределы цикла, и не парить голову ни себе, ни компилятору.

А так, тут два момента:

1. strlen возвращает длину строки. Которая может измениться внутри тела цикла. Что-то я очень сомневаюсь, что компиляторы в состоянии проконтролировать такое. Но если реально проконтролирует, что в теле цикла значение строки не меняется - запросто оптимизирует.

2. Стандартные функции обычно запиливают под специфик-компилятора. Они запросто могут иметь специфик-деррективы, которые помогают компилятору оптимизировать их.

Честно говоря, я не знаю ответа на твой вопрос. Надо смотреть что компилятор породит. Но думаю, что компилятор самостоятельно не сумеет догадаться, подставить константу вместо strlen

Но я знаю, что компилятор попытается это сделать.
И если компилятор догадается, что при одном и том же аргументе, результат вычисления функции будет один и тот же - то он самостоятельно этот момент может оптимизировать:

Код:
int a=10, b=10;
...
for(size_t n=0; n< a*b; ++n) { /*что-то делаем*/}
...
Умножение - дорогая операция. Компилятор сам преобразует цикл к виду:

Код:
int a=10, b=10;
...
const int tmp = a*b;
for(size_t n=0; n< tmp; ++n) { /*что-то делаем*/}
...
Однако! Если теоретически есть вероятность, что результат вычисления функции рантайм-нестабильный, то никаких оптимизаций не будет:


Код:
volatile int a=10;
int b=10;
...
for(size_t n=0; n< a*b; ++n) { /*что-то делаем*/}
...
Ключевое слово volatile сообщает компилятору, что значение переменной val может "вдруг" измениться. Например - из соседнего потока.

Поэтому выражение a*b не является константой, и её поведение компилятор предсказать уже не сможет.


Что касается обычных функций программиста, то компиль сможет оптимизировать цикл, только если эта функция какая нибудь простейшая inline
_Bers вне форума Ответить с цитированием
Старый 03.06.2012, 02:06   #12
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

Спасибо, Вам, Берс!
Прекрасно объяснили!

Вопрос немного не по теме..
Зачем применять size_t если можно просто int ?
Я часто вижу применение size_t..
Спеши медленно.
asmars вне форума Ответить с цитированием
Старый 03.06.2012, 11:50   #13
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от asmars Посмотреть сообщение
Спасибо, Вам, Берс!
Прекрасно объяснили!

Вопрос немного не по теме..
Зачем применять size_t если можно просто int ?
Я часто вижу применение size_t..
Тип данных int является знаковым. Может быть как положительным, так и отрицательным числом.

Предположим что тебе нужен счетчик цикла, значение которого по смыслу является индексом элемента массива.

Индекс элемента массива может быть отрицательным?
А если индекс элемента не может быть отрицательным, почему ты в качестве индекса допускаешь тип данных, который может применять отрицательные числа?

Правило очень простое: то, чего быть не должно - не должно произойти в принципе.

Если тебе нужен индекс массива - используй беззнаковые типы, и это гарантирует, что значение индекса всегда будет больше или равно нулю.

Превентивная форма защиты от возможных ошибок.

size_t по смыслу нужно читать так: "тип, значением которого является размер типа данных". И по идее использовать его нужно тогда, когда требуется вернуть размер данных ( результат работы sizeof() )

Для беззнаковых интов правильнее использовать unsigned int
Однако, меня парит писать длинные два слова, когда по сути тоже самое
делает size_t. Коротко, и лаконично.

Важно понимать, что size_t может оказаться не тем же самым, что и unsigned int (хотя лично я не встречал различий. Но они могут быть в 64битных системах). Однако size_t гарантированно беззнаковый. Так же, как и unsigned int. И для работы с беззнаковыми целыми ничем не отличается от unsigned int (если не требуется пасти различия между sizeof(size_t) и sizeof(unsigned int).
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
void to struct (C++) slim>>> Помощь студентам 1 13.01.2011 20:52
Struct, union HeLiO Общие вопросы C/C++ 6 29.12.2010 12:16
Struct mansp Общие вопросы C/C++ 4 05.12.2010 20:00
Вопрос по Struct cheblya Общие вопросы C/C++ 2 06.11.2009 11:42
STRUCT() alexov Общие вопросы C/C++ 1 13.01.2009 18:13