2013-06-25 5 views
7

Мне было интересно, влияет ли объявление нескольких вещей того же типа на время компиляции, например ниже.Влияют ли множественные объявления одного типа на время компиляции?

void a(), 
    b(), 
    c(); 

против

void a(); 
void b(); 
void c(); 
+10

Почему кто-то на земле будет использовать первую форму? Это не очень дружелюбно. – banuj

+2

Балог: это необычно, но это совершенно верно. Точно так же это объявление также справедливо: 'int a, * b, c [4], d (float), (* e) (char);'. Он объявляет int, int pointer, массив ints, функцию, возвращающую int (и принимая float), и указатель на функцию, возвращающую int (и беря символ). Это уродливо, но верно C. –

+3

Хорошо, что мы ничего не знаем, это попробовать. И я не понимаю, почему этот вопрос отрицается. –

ответ

6

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

Как правило, некоторые из основной структуры современного компилятора:

  • Существует часть, которая читает каждый символ, соответствуют символам на простые узоры (например, «последовательность букв и цифр, начиная с «письмо» или «+» или «/ * текст * /» и упаковывает их в токены с дополнительными данными (идентификатор с текстом для имени, оператор типа +, пробел). Эта часть называется лексическим анализатором.
  • Есть часть, которая получает маркеры и анализирует их синтаксическую структуру.
  • Другие детали, которые нас здесь не касаются.

Та часть, которая анализирует синтаксическая структура делает что-то вроде этого: Когда он признает a() в декларации, такие как void a(), он вызывает подпрограмму в другом месте в компиляторе, который регистрирует a в качестве идентификатора с типом function returning void. Это происходит, когда распознается a(), когда признается b(), и когда признается c().

Важно в данном случае является то, что то же самое происходит с обеих предложенных кодовых последовательностей: a(), b() и c() все признали, и та же последовательность обычных вызовов производится зарегистрировать эти идентификаторы. С этого момента их обработка идентична. В типичных компиляторах не будет различий в способе обработки a(), b() и c().

Это означает, что единственная разница в обработке этих кодовых последовательностей компилятором заключается в лексическом анализаторе и процессоре синтаксиса. Для одной из кодовых последовательностей есть еще несколько символов и еще несколько токенов, так что последовательность кода, скорее всего, займет немного больше времени для обработки. Однако со скоростью сегодняшних компьютеров такое количество времени незначительно.

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

6

не заметно. Не беспокойтесь об этом.

+1

Я бы посоветовал использовать вторую форму в качестве стиля, но разница во времени компиляции вряд ли будет значительной, и ваше время лучше потрачено, беспокоясь о вашем фактическом коде, количество кода, в котором вы находитесь # включение и т. д. –

4

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

0

Конечно, это то же самое. Никто не напишет первое издание.

+2

, по крайней мере, будем надеяться, что он никогда не выживет в обзоре. –

7

Я был бы удивлен, если бы не было вообще, поскольку компилятор выполнит разный код для двух случаев, но невозможно угадать, какой из них будет быстрее, и один будет последовательно быстрее другого.

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

Если у вас возникли проблемы со временем компиляции, стиль объявления не является причиной.

+0

Кроме того, небольшие различия, вероятно, будут отличаться между компиляторами. –

0

Вопрос стоит спросить. Если вы придерживаетесь привычки и смотрите, как ваш компилятор фактически преобразует ваш код на C++ в сборку, это проще ответить: два определения будут выводить один и тот же код сборки. Например, я скомпилировал небольшой тест (используя вход и выход, чтобы избежать оптимизации с постоянной сгибанием), и две версии выдают один и тот же точный двоичный файл (по аналогии идентичный).

#include <iostream> 
int main(int argc, const char * argv[]) 
{ 
    int a, b; 
    std::cin >> a >> b; 
    std::cout << a << b; 
} 

#include <iostream> 
int main(int argc, const char * argv[]) 
{ 
    int a; 
    int b; 
    std::cin >> a >> b; 
    std::cout << a << b; 
} 

Если вы идете увидеть разборку, вы увидите ИНТ декларация составляются на что-то вроде:

0x100000ef6: movq %rsi, -16(%rbp) 

Независимо синтаксис вы используете, чтобы сказать ему, есть только один способ Оставляет переменным пространство на уровне сборки. Все компиляторы зарезервируют локальное переменное пространство только в одной инструкции.

+2

Кажется, вы отвечаете с точки зрения времени выполнения, но вопрос о времени компиляции. –

+0

Ох. Мой плохой, thx ^^ – lip

0

Оба они одинаковы, но всегда полезно использовать второй, чтобы код был более структурированным, читаемым и будет легко понят каким-либо другим человеком, кроме вас. Первая добавит больше путаницы.

2

Зачем нужно 1 вариант?

Оба кажутся мне в то же время, так как это объявление. Компилятор возьмет каждую из трех пустот, даже пустота будет написана трижды. Но подробно рассмотрим время компиляции.

А если серьезно, то Программист пойдет на второй, так как он является обязательным знаком стандартов написания кода, ведущих к красоте кода.