Указание функции не имеет побочных эффектов [дубликат]

Это WORKS ..

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

Первый контроллер

try {
                                Stage st = new Stage();
                                 FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/inty360/free/form/MainOnline.fxml"));

                                Parent sceneMain = loader.load();

                                MainOnlineController controller = loader.<MainOnlineController>getController();
                                controller.initVariable(99L);

                                Scene scene = new Scene(sceneMain);
                                st.setScene(scene);
                                st.setMaximized(true);
                                st.setTitle("My App");
                                st.show();
                            } catch (IOException ex) {
                                Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
                            }

Другой контроллер

public void initVariable(Long id_usuario){
        this.id_usuario = id_usuario;
        label_usuario_nombre.setText(id_usuario.toString());

    }
13
задан imre 8 July 2011 в 12:40
поделиться

3 ответа

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

char * str = get_some_string();
for ( int i = 0; i < strlen( str ); ++i ) {
    str[i] = toupper(str[i]);
}

Может быть оптимизирован компилятором в:

char * str = get_some_string();
int __length = strlen( str );
for ( int i = 0; i < __length; ++ i ) {
   str[i] = toupper(str[i]);
}

Функция объявлена ​​в строке .h header as:

extern size_t strlen (__const char *__s)
     __THROW __attribute_pure__ __nonnull ((1));

Где __THROW - исключение без исключения в случае, если он является компилятором C ++, анализирующим функцию, а __nonnull((1)) сообщает компилятору, что первый аргумент не должен быть null (т. е. вызвать предупреждение, если аргумент имеет значение null и используется флаг Wnonnull).

16
ответ дан David Rodríguez - dribeas 19 August 2018 в 09:44
поделиться
  • 1
    Это выглядит многообещающе. Кто-нибудь знает что-то подобное в MSVC? (Конечно, стандартное решение было бы лучше, но хорошо ...) – imre 8 July 2011 в 12:56
  • 2
    @David: знаете ли вы, что компилятор делает какие-либо проверки, если вы используете определение функции по чистоте? – Matthieu M. 8 July 2011 в 12:57
  • 3
    @imre: Если у вас установлен MSVC, попробуйте взглянуть на strlen, он может иметь аналогичный атрибут, это хороший пример функции, которая известна в стандарте как pure так что это был бы хороший кандидат, чтобы разработчики могли использовать этот атрибут. – David Rodríguez - dribeas 8 July 2011 в 12:59
  • 4
    @Matthieu M. Я не думаю, что компилятор выполняет эту проверку. Атрибут не может использоваться в определении функции только в объявлении, а это, в свою очередь, означает, что компилятор может не видеть, что функция была объявлена ​​чистой, поэтому у нее может не быть необходимой информации, чтобы вызвать предупреждение / ошибку , Простой тест с g ++ 4.5.2 не дал никаких предупреждений в функции, которая имела побочные эффекты, но была объявлена ​​чистой. – David Rodríguez - dribeas 8 July 2011 в 13:03
  • 5
    Просто нашел это: stackoverflow.com/questions/2798188/… – imre 8 July 2011 в 13:10

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

Чтобы добиться того, чего вы хотите со 100% уверенностью, вам нужно обернуть весь оператор макросом, который будет оценивать пустой оператор для вашей конфигурации выпуска.

4
ответ дан Alex B 19 August 2018 в 09:44
поделиться
  • 1
    Как обернуть заявление в макрос, чтобы помочь? К моменту, когда код попадает в собственно компилятор, этот макрос не существует. Он был расширен. Правка Ничего. В рабочем режиме макрос не расширяется. – David Hammen 8 July 2011 в 12:50
  • 2
    @David, я должен был быть более явным. Ред. – Alex B 8 July 2011 в 12:53
  • 3
    Да, я знаю о возможности обертывания всего этого в одном макросе, но мне это не нравится в качестве решения по двум причинам: а) он немного уродлив, и б) почему-то я чувствую, что даже если бы сейчас я мог только придумайте эти два примера, это на самом деле более общая проблема, и способность флага выполнять функции без побочных эффектов может иметь дальнейшее применение. Оптимизация только встроенных функций на самом деле недостаточно; аргумент функции может быть результатом очень сложного вычисления (без побочных эффектов), и если его игнорировать, было бы неплохо пропустить весь вызов. – imre 8 July 2011 в 12:55
  • 4
    @imre, ну, если вы так выразились, нет (переносной) поддержки языка. Вы либо используете языковые расширения, специфичные для компилятора, либо другие функции (такие как оптимизация времени соединения, где доступ к дополнительной информации о функциях доступен через модули кода). – Alex B 8 July 2011 в 13:00
  • 5
    Я считаю, что вы здесь не правы: если GetCategory () объявлен как «чистый», как рекомендовано первым ответом, и если результат GetCategory () не используется вызывающим кодом, вызов GetCategory () будет оптимизироваться GCC! Даже если код GetCategory () НЕ установлен. Это может быть легко протестировано - например, в следующем фрагменте кода компилятор выдает вызов «g», но не вызывает «f»: int f (int x) __attribute __ ((чистый)); int g (void); void h (void) {f (g ()); } – Kai Petzke 20 January 2014 в 21:07

Это проблема с кодом режима отладки.

Единственное надежное решение (для вызовов функций) - это весь код отладки внутри самого макроса.

Для Например, вы могли бы использовать следующий код вместо этого:

LOG("message", GetCategory());

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

3
ответ дан Matthieu M. 19 August 2018 в 09:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: