До того как Вы определили A::i компилятору нужно создать глобальный экземпляр класса и ему нужно знать куда ссылается A::i. Мне кажется такой ситуации не возникло бы, если бы MQL5 код сначала компилировался в объектные файлы, а потом компоновался в исполняемый (на пример как в С/С++).
А на вопрос про принципиальную разницу я ответил в предыдущем сообщении. Здесь ровно та же самая ситуация в певом случае имеем только указатель на экземпляр (объект) класса, во втором сам экземпляр.
Вообще-то, адрес, по которому разыменовывать A::i компилятору известен))) Ну, конечно, если это С++))). Требование инициализации статических полей класса происходит из того, что Declaration of a non-inline(since C++17)static data member inside a class definition не является definition. https://en.cppreference.com/w/cpp/language/definition На лицо, явный баг компилятора.
Vladimir Simakov #: Вообще-то, адрес, по которому разыменовывать A::i компилятору известен))) Ну, конечно, если это С++))). Требование инициализации статических полей класса происходит из того, что Declaration of a non-inline(since C++17)static data member inside a class definition не является definition. https://en.cppreference.com/w/cpp/language/definition На лицо, явный баг компилятора.
У нас тут MQL обсуждался, но раз пошел разговор за плюсы, то объясните мне, пожалуйста, откуда компилятору может быть известен адрес того, чего нет?
Вот простой кусок кода на C++.
class A
{
public:
staticint i;
};
A a;
int main()
{
int i = a.i;
return0;
}
И только компоновщик при попытке собрать исполняемый файл выдает ошибку.
/usr/bin/ld: /tmp/ccZMtngh.o: warning: relocation against `_ZN1A1iE' in read-only section `.text'
/usr/bin/ld: /tmp/ccZMtngh.o: in function `main':
a.cpp:(.text+0xa): undefined reference to `A::i'
Которую я понимаю как: упс, у меня здесь есть некий символ _ZN1A1iE и я не понимаю что подставить на его место
Если добавить определние статической переменной
class A
{
public:
staticint i;
};
int A::i = 777;
A a;
int main()
{
int i = a.i;
return0;
}
То в ассемблере добавляется блок с описанием этой _ZN1A1iE
Если объявляете статическую переменную, то следует ее и определить.
Попробуйте добавить в класс метод обращающийся к переменной и уже получите ошибку компиляции в коде класса
А принципиальная разница между вашими случаями (1) и (2) следующая (очень грубо):
Во втором случае вы объявляете глобальную переменную-экземпляр класса. Компилятору необходимо выделить память для нее и всего связанного с классом и здесь же компилятор пытается понять куда указывает имя `A::i`.
А в первом случае вы объявляете глобальную переменную-указатель на экземпляр класса. Здесь компилятору надо выделить память только для указателя, а сам объект будет создан уже в процессе выполнения программы.
И в первом и во втором случае создаётся объект класса A
У нас тут MQL обсуждался, но раз пошел разговор за плюсы, то объясните мне, пожалуйста, откуда компилятору может быть известен адрес того, чего нет?
Вот простой кусок кода на C++.
Из него генерится примерно такой ассемблерный код
У нас здесь есть только название чего-то
И только компоновщик при попытке собрать исполняемый файл выдает ошибку.
Которую я понимаю как: упс, у меня здесь есть некий символ _ZN1A1iE и я не понимаю что подставить на его место
Если добавить определние статической переменной
То в ассемблере добавляется блок с описанием этой _ZN1A1iE
И все нормально собирается.
Если под "известный компилятору адрес" Вы имели ввиду это самое название на которое он может ссылаться, то ок. Иначе прошу объяснений :)
Это не название чего-то, это имя метки. Вы не дочитали мой пост до конца или не поняли. Поясняю.
Есть Declaration, это когда мы объявили переменную. Компилятор абсолютно спокойно вводит имя метки и везде, где нужно делает rip адресацию через нее. Поэтому я и говорю, что компилятор ЗНАЕТ адрес переменной, потому, что эта метка должна появится потом и компоновщик вычислит смещение до нее и на выходе, естественно, не будет никаких меток, а будет вот это:
Такое ощущение, что не весь синтаксис SQLite поддерживается
input string str_Marka="ЗИЛ";//Марка
input string str_Model="КО";//Модель
...
string sql_query =
"SELECT ""a.Id, ""a.Title, ""m.Value AS 'Марка', ""mo.Value AS 'Модель', ""y.Value AS 'Год выпуска', ""(SELECT u_min.Time_db FROM Adv_update u_min WHERE u_min.Adv_Id = a.Id ORDER BY u_min.Time_db ASC LIMIT 1) AS 'Наименьшая дата', ""(SELECT u_min.Price FROM Adv_update u_min WHERE u_min.Adv_Id = a.Id ORDER BY u_min.Time_db ASC LIMIT 1) AS 'Цена для наименьшей даты', ""(SELECT u_max.Time_db FROM Adv_update u_max WHERE u_max.Adv_Id = a.Id ORDER BY u_max.Time_db DESC LIMIT 1) AS 'Наибольшая дата', ""(SELECT u_max.Price FROM Adv_update u_max WHERE u_max.Adv_Id = a.Id ORDER BY u_max.Time_db DESC LIMIT 1) AS 'Цена для наибольшей даты' ""FROM ""Adv AS a ""JOIN Adv_Prop AS m ON a.Id = m.Adv_Id AND LOWER(m.Name) = 'Марка' AND LOWER(m.Value) = LOWER('" + str_Marka + "') ""JOIN Adv_Prop AS mo ON a.Id = mo.Adv_Id AND LOWER(mo.Name) = 'Модель' AND LOWER(mo.Value) LIKE LOWER('%" + str_Model + "%') ""JOIN Adv_Prop AS y ON a.Id = y.Adv_Id AND LOWER(y.Name) = 'Год выпуска' ";
Если я ввожу str_Marka="зил", то получаю пустой ответ - иначе говоря, оператор LOWER ничего не делает. При значении ЗИЛ - всё ищется - в базе записано "ЗИЛ" Можете это проверить?
Такое ощущение, что не весь синтаксис SQLite поддерживается
Если я ввожу str_Marka="зил", то получаю пустой ответ - иначе говоря, оператор LOWER ничего не делает. При значении ЗИЛ - всё ищется - в базе записано "ЗИЛ" Можете это проверить?
Почему С\С++ создает исполняемый файл без ошибок, а в MQL ошибка уже на этапе компиляции?
Потому что компиляторы С/С++ и MQL работают по-разному. Очевидно же :)
А в чем принципиальная разница работы, применительно к конкретному примеру?
Чем MQL компилятор хуже C\C++ ?
До того как Вы определили A::i компилятору нужно создать глобальный экземпляр класса и ему нужно знать куда ссылается A::i. Мне кажется такой ситуации не возникло бы, если бы MQL5 код сначала компилировался в объектные файлы, а потом компоновался в исполняемый (на пример как в С/С++).
А на вопрос про принципиальную разницу я ответил в предыдущем сообщении. Здесь ровно та же самая ситуация в певом случае имеем только указатель на экземпляр (объект) класса, во втором сам экземпляр.
Вообще-то, адрес, по которому разыменовывать A::i компилятору известен))) Ну, конечно, если это С++))). Требование инициализации статических полей класса происходит из того, что Declaration of a non-inline (since C++17) static data member inside a class definition не является definition. https://en.cppreference.com/w/cpp/language/definition На лицо, явный баг компилятора.
У нас тут MQL обсуждался, но раз пошел разговор за плюсы, то объясните мне, пожалуйста, откуда компилятору может быть известен адрес того, чего нет?
Вот простой кусок кода на C++.
Из него генерится примерно такой ассемблерный код
main: ..................... movl _ZN1A1iE(%rip), %eax movl %eax, -4(%rbp) .....................У нас здесь есть только название чего-то
И только компоновщик при попытке собрать исполняемый файл выдает ошибку.
Которую я понимаю как: упс, у меня здесь есть некий символ _ZN1A1iE и я не понимаю что подставить на его место
Если добавить определние статической переменной
То в ассемблере добавляется блок с описанием этой _ZN1A1iE
И все нормально собирается.
Если под "известный компилятору адрес" Вы имели ввиду это самое название на которое он может ссылаться, то ок. Иначе прошу объяснений :)
Вот простой кусок кода на C++.
Из него генерится примерно такой ассемблерный код
А какое отношение этот код имеет к моему примеру?
У меня речь о том, что при прочих равных условиях в одном случае ошибка, а в другом ее нетЕсли объявляете статическую переменную, то следует ее и определить.
Попробуйте добавить в класс метод обращающийся к переменной и уже получите ошибку компиляции в коде класса
А принципиальная разница между вашими случаями (1) и (2) следующая (очень грубо):
Во втором случае вы объявляете глобальную переменную-экземпляр класса. Компилятору необходимо выделить память для нее и всего связанного с классом и здесь же компилятор пытается понять куда указывает имя `A::i`.
А в первом случае вы объявляете глобальную переменную-указатель на экземпляр класса. Здесь компилятору надо выделить память только для указателя, а сам объект будет создан уже в процессе выполнения программы.
У нас тут MQL обсуждался, но раз пошел разговор за плюсы, то объясните мне, пожалуйста, откуда компилятору может быть известен адрес того, чего нет?
Вот простой кусок кода на C++.
Из него генерится примерно такой ассемблерный код
У нас здесь есть только название чего-то
И только компоновщик при попытке собрать исполняемый файл выдает ошибку.
Которую я понимаю как: упс, у меня здесь есть некий символ _ZN1A1iE и я не понимаю что подставить на его место
Если добавить определние статической переменной
То в ассемблере добавляется блок с описанием этой _ZN1A1iE
И все нормально собирается.
Если под "известный компилятору адрес" Вы имели ввиду это самое название на которое он может ссылаться, то ок. Иначе прошу объяснений :)
Это не название чего-то, это имя метки. Вы не дочитали мой пост до конца или не поняли. Поясняю.
Есть Declaration, это когда мы объявили переменную. Компилятор абсолютно спокойно вводит имя метки и везде, где нужно делает rip адресацию через нее. Поэтому я и говорю, что компилятор ЗНАЕТ адрес переменной, потому, что эта метка должна появится потом и компоновщик вычислит смещение до нее и на выходе, естественно, не будет никаких меток, а будет вот это:
Поясняю.
Такое ощущение, что не весь синтаксис SQLite поддерживается
Если я ввожу str_Marka="зил", то получаю пустой ответ - иначе говоря, оператор LOWER ничего не делает. При значении ЗИЛ - всё ищется - в базе записано "ЗИЛ"
Можете это проверить?
Такое ощущение, что не весь синтаксис SQLite поддерживается
Если я ввожу str_Marka="зил", то получаю пустой ответ - иначе говоря, оператор LOWER ничего не делает. При значении ЗИЛ - всё ищется - в базе записано "ЗИЛ"
Можете это проверить?
Похоже на проблемы с локалью.