Ошибки, баги, вопросы - страница 2860

 
Это правильное поведение компилятора?
class A
{
public:
  static int i;
  
  static int f()
  {
    A::i = 123;
    
    return(A::i);
  }
};

static int A::i = A::f();

void OnStart()
{
  Alert(A::i); // 123
}
Вроде, A::i не создана на момент вызова метода A::f(), в котором идет обращение к A::i.
 
fxsaber:
Это правильное поведение компилятора? Вроде, A::i не создана на момент вызова метода A::f(), в котором идет обращение к A::i.

Что подразумевается под словом "создана" ?

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

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

Документация по MQL5: Основы языка / Переменные / Создание и уничтожение объектов
Документация по MQL5: Основы языка / Переменные / Создание и уничтожение объектов
  • www.mql5.com
После загрузки на исполнение mql5-программы каждой переменной выделяется память в соответствие с типом переменной. Переменные делятся на два типа по уровню доступа - глобальные переменные и локальные переменные, и по классам памяти: входные параметры mql5-программы, статические и автоматические. Каждая переменная при необходимости...
 
Ilyas:

В приведённом примере прокатило...

Менять в этом месте будете компилятор? Лично я бы хотел, чтобы все осталось так, как есть.

 
fxsaber:

Менять в этом месте будете компилятор? Лично я бы хотел, чтобы все осталось так, как есть.

Поведение менять не планируем.

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

Документация по MQL5: Основы языка / Переменные / Глобальные переменные
Документация по MQL5: Основы языка / Переменные / Глобальные переменные
  • www.mql5.com
Глобальные переменные создаются путем размещения их объявлений вне описания какой-либо функции. Глобальные переменные определяются на том же уровне, что и функции, т. е. не локальны ни в каком блоке. Область видимости глобальных переменных - вся программа, глобальные переменные доступны из всех функций, определенных в программе...
 
Ilyas:

Если фичу реализуем, то  при компиляции приведённого кода получите предупреждение: для инициализации A::i используется функция A::f(), в которой осуществляется доступ к инициализируемой переменной A::i.

Спасибо!

 
Ilyas:

Поведение менять не планируем

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

int i = i; //Error: 'i' - undeclared identifier
В хорошем языке - единые правила, а не наоборот
 
A100:

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

В хорошем языке - единые правила, а не наоборот

Я вооще профан, но до такого (int i = i) я бы и с перепою не додумался....... 8(

 
Сергей Таболин:

Я вооще профан, но до такого (int i = i) я бы и с перепою не додумался....... 8(

А в чем принципиальное отличие от исходного примера? Уберите лишнее и получите:

int i = i = 123; //Error: 'i' - undeclared identifier

Только там куча строк, а здесь - всего одна

Если там нет ошибки при компиляции, то и здесь не должно быть (и наоборот), а иначе - бардак

 
A100:

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

В хорошем языке - единые правила, а не наоборот
В данном случае все ок.

Речь о том, что можно получить в других, более хитрых условиях неопределенное поведение. Самострелы в С++ реализуемы.
 
A100:

А в чем принципиальное отличие от исходного примера? Уберите лишнее и получите:

Только там куча строк, а здесь - всего одна

Если там нет ошибки при компиляции, то и здесь не должно быть (и наоборот), а иначе - бардак

Вы не правы, это не одно и то же.

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