- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
#include <iostream>
#include <map>
struct A {
const static int i = 10;
};
using namespace std;
int main()
{
map<int, string> m;
m[0] = "zero";
m[A::i] = "A::i"; // Не везде работает
cout << A::i << endl;
return 0;
}
P.S. Кстати у меня и 4.6.3 тоже не собирает с ошибкой undefined reference to `A::i'.
Я не очень понял, что следует из стандарта и этой связи с компиляторным багизмом.
Интересно, что если использовать идентификатор просто для вывода, то он считается определенным, а если как ключ для мапы - то хуй.
Но если мы юзаем эту константу где-то в другом месте, где константность не обязательна - компилятор может не захотеть подставлять ее значение, а оставит ее как обычную переменную, и тут то линкер свалится с ошибкой "undefined reference".
P.S. А может и подставить, и тогда все будет компилиться и работать, откладывая баттхерты на потом.
всё-таки странно, что на разных версиях GCC сначала не работает - потом работает - потом опять не работает. (судя по liveworkspace).
Мне это даже напомнило цитатку из вики про #pragma once http://en.wikipedia.org/wiki/Pragma_once:
GCC originally gave a warning declaring #pragma once "obsolete" due to a problem with symbolic and hard links. However, this problem was fixed in GCC 3.4, and the feature was "un-deprecated" and the warning removed.
На самом деле, если следовать стандарту, проблема не так ужасна. Юзаешь только в тех местах, где допустимы только константы? Достаточно будет struct A { const int i = 100500 }. Юзаешь где-то еще? Добавляй в сипипишку, посвященную данному классу const int A::i.
https://ideone.com/zQDd5H
https://ideone.com/Zc7sLF
https://ideone.com/6Oaow3
Ничего не понимаю, и это компилятор. Говно какое-то, недетерминированное, блядь. Ему статику в неймспейсе дали- подставляй. Подставляй константы, блядь!
Не хочу, хочу передавать как undefined reference! Что такое? Это С++? Это С++? Оптмизации включил, по ссылке передаёт - пидор ебучий, блядь.
Как показала практика шитштормы устраивались из-за пары, а иногда и одной строчки.
Потому С++
Ну что, никто не знает?
так что 1) вместо static const int пользуйся enum, врядли тебе нужен будет где то _адрес_, а не значение
2) раз уж все равно большую часть присваивать вне класса, почему бы всё не присваивать вне класса
и да, в студии код из ОП работает, понятное дело
Работоспособность этого кода не противоречит стандарту... равно как и неработоспособность.
P.S. Хотя гарантированно работающим он бы мне больше нравился.
PS: Роман уже отписался ниже
P.S. Забавно было смотреть, как мой корректный код который, к слову, работал в шестой визуалке, отвергался 2003й потому что "ISO сменило скопы", и единственным портабельным способом между 6, 2003 и 2005 был старый добрый сишный
и не только в 2005
в этом плане я придерживаюсь следующего:
собственно, в чем проблема - ну временный объект, ну поменяет его функция - функции то всё равно насрать, что станет с тем объектом, а если мы туда передали временный объект - значит и нам насрать
Кресты... не компилируется. Оказалось, get() принимает аргумент по ссылке, а у константы нет адреса.
У констант есть адрес.
А вот передать константу как переменную по ссылке не получится.
If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions within its scope. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.
Следующий вариант решает проблему:
теперь я кажется понял, почему кушает в cout.
p.s. или не понял :)
1.3. You DO NOT talk about Undefined behavior!
причудился питоновский срез...
The fact that it works at O3 is pure luck and not a bug.
gcc.gnu.org/bugzilla/show_bug.cgi?id=11203
Я понимаю что это кресты, но речь об отношении gcc в целом.
А при чем тут кресты? Проблема же вылезла уже при раздаче регистров: "error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'", на этом этапе никаких крестов уже нет.
А автор, имхо, сам виноват: там в конце инлайн вставки слишком дохера "m" параметров. Т.к. многие из описанных там кусков памяти находятся не в стековом фрейме и не в глобалках, компилятор должен поместить их адрес перед асмовставкой в какой-то регистр (т.к. он не имеет права добавлять дополнительные инструкции внутрь вставки). А регистров на x86 мало (всего 8, из которых 2 заняты стеком (esp) и стековым фреймом (ebp) (т.к. на -O0 выключен -fomit-frame-pointer)).