2016-02-11 4 views
3

Я играл с C++ раньше и думал, если в некоторых случаях Поскольку мой C компилятор отказывается позволить мне писать код, такой как:Какова стоимость безымянного объема в C?

for (int i = 0; i < 30; ++i) 
{ 
    ... 
} 

Я стараюсь писать что-то вроде:

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    { 
     int i; 
     for (i = 0; i < 30; ++i) { 
      printf("%d.\n", i); 
     } 
    } 

    return 0; 
} 

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

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    int i = 3; 

    /* my loop scope. */ 
    { 
     int i; 
     for (i = 0; i < 30; ++i) { 
      printf("%d.\n", i); 
     } 
    } 
    printf("i remains intact! %d.\n", i); 

    return 0; 
} 

Опять же, я бы не намеренно сделать реальный код для злоупотреблений я люблю это, но во многих случаях, особенно касающихся временных переменных, необходимых в вызовах LibC функций, таких как sem_getvalue или Windows API FormatMessage, где легко загромождать область применения многими временными переменными и путаться с тем, что происходит. Используя неназванные области, теоретически, я мог бы уменьшить сложность моего кода, изолировав эти временные переменные до неназванных областей.

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

+4

Пожалуйста, получите компилятор C99 для переменных с переменными 'for'. Они не так редки. – unwind

+0

Мне было интересно использовать неназванные области для временных переменных, которые необходимо выполнить перед вызовами функций, которые также хранят результаты этих функций. Меня просто интересует неназванная конструкция сама по себе, есть ли какая-то особая причина, чтобы ее избежать? – Dmitry

+1

«Стоимость» объявления переменных во вложенной области - это пространство хранения этих переменных. Вот и все. –

ответ

5
{ 
    int x = 3; 
    { 
    int y = 4; 
    int sum = x+y; 
    } 
} 

не имеет больше затрат, чем:

{ 
    int x = 3; 
    int y = 4; 
    int sum = x+y; 
} 

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

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

+0

Я думал об этом, но казалось слишком хорошим, чтобы быть правдой, поскольку, когда y и sum покидают область действия, они больше не должны занимать пространство стека (в отличие от полномасштабной переменной, которая продолжается в течение всего область охвата даже после того, как она больше не нужна), поскольку они выходят из стека, когда область выходит. Это действительно так? – Dmitry

+1

Я думаю, что это не стоит так думать, потому что вы ошибаетесь в 9 раз из 10. Компилятор может использовать линейные методы и использовать пространство стека, поэтому вы никогда не сможете предсказать, что действительно произойдет. например 'sum' в моем примере может фактически находиться в том же стеке, что и' x', потому что после этого 'x' не будет использоваться снова. – weston

+0

Но при отсутствии оптимизаций, не так ли? – Dmitry

0

Я не думаю, что локальное распределение переменных работает так, как вы думаете.

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

4

высвобождает я должен использоваться для других целей, в основном объеме

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

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

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

Если вам нужна i с разным типом в разных местах функции, это явный признак того, что вы должны разделить функцию на несколько.

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

+0

Мне это хорошо известно. Мой вопрос касался того, что стоит использовать конструкцию. Поэтому я намерен использовать его, когда считаю, что это оправданно. Просто потому, что у меня есть гибкость, чтобы сделать это, не означает, что я буду использовать его так, чтобы он повсюду обфускал обычные переменные и мой код. Но этот метод кажется интересным применять при работе с временными переменными, такими как sem_getvalue integer, и lpBuffer в FormatMessage (Windows API). Это упрощает мой код, исключая временные переменные из локальной области во временную область. – Dmitry

+0

@Dmitry Область и хранение - это две разные вещи. С точки зрения эффективности, нет никаких затрат.Компилятор будет выделять пространство при необходимости и освобождать его при необходимости, независимо от того, где объявлена ​​определенная переменная_. Область действия сводится только к ограничению переменных для преднамеренного/непреднамеренного использования вне кода, где имеет смысл использовать эту переменную. – Lundin

+0

Это моя точка зрения. Эти временные переменные не имеют смысла использоваться вне этой области, они только путают/подавляют читателя, увеличивая количество переменных в локальной области. Мне было любопытно, если использовать его для этой цели было любой ценой, о которой я не знал. Из того, что я собираю, это кажется идеальным решением для уменьшения помех объема, перемещая его во временные области, где они имеют смысл. – Dmitry

Смежные вопросы