Не получается преобразование нуль-терминальной UTF8 в std::wstring

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Аватара пользователя
Сионист
Сообщения: 1077
Зарегистрирован: 31 мар 2014, 06:18

15 дек 2015, 06:31

1. В этом завале абсолютно не очевидно.
2. А такой вообще есть?
3. Что он делает?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

15 дек 2015, 09:08

Да что ж ты, как ребёнок малый? Неужели обязательно нужно тыкать и объяснять всё? Открой гугл и узнай, что делает конструктор.

Я понимаю, когда школьники или студентики начальных курсов не могут ни в чём разобраться сами. Они не привыкли ещё самостоятельно работать. Но ты же дядька уже...
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1077
Зарегистрирован: 31 мар 2014, 06:18

15 дек 2015, 13:33

Absurd писал(а):Поэтому макросам дают такие имена чтобы не напарываться
. В большом проекте с обилием чисел. Костыль - не заплатка, тем более если он ещё и из спичек.
Absurd писал(а):

Код: Выделить всё

void f1()
{
 const float x=20.3;
}
void f2()
{
 const float x=30.64;
}
Зачем тут вообще ставить const?
А зачем вообще нужны константы?
Absurd писал(а):Стек вообще RW память, const в нем нельзя реализовать физически.
Энто кто тебе сказал?
Absurd писал(а):

Код: Выделить всё

struct Q {
  float nefarious[1];
  const float x = 20.3;
};

int main()
{
  Q q;
  // q.x = 666.0f; Не компилируется
  q.nefarious[1] = 666.0f;
  std::cout << q.x;
  return 0;
}
У меня выводит 666
Потому что константа неявно приведена к переменной путём выхода за границу массива. Можно и чуть явней

Код: Выделить всё

uniont Q {
  float nefarious[1];
  const float x = 20.3;
};
int main()
{
 Q.nefarious[0]=666;
 std::cout<<Q.x;
 return 0;
}
и даже выравнивание значения иметь не будет. const защищает данное от изменение только при доступе по его имени, а если плясать с бубном на тему "А давайте сверху кинем переменную", то ни кто великому чукотскому писателю не виноват, что он так странно пишет. Константный указатель тоже защищает лишь от изменения с использованием самого константного указателя, но не через другой указатель и не так:

Код: Выделить всё

int x=6;
const int *p=&x;
x=23;
. И от того, что данное объявлено статически, или глобально, или вообще лежит в куче ничего не меняется.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

16 дек 2015, 02:45

В большом проекте с обилием чисел. Костыль - не заплатка, тем более если он ещё и из спичек
Ну ИМХО Unreal это достаточно большой проект при всем том.
Зачем тут вообще ставить const?
А зачем вообще нужны константы?
Тут мы имеем дело с языком С++, то есть с тридцатилетней эволюцией комплексов мистера Бьорна Строуструпа, устаревших трендов, ошибочных концепций, тупиковых идей, несбывшихся надежд, шумихи начала 90-х, моды на ООП, анти-сиплюсплюсной реакции после появления Джавы, неожиданно удачного применения фичей С++ для решения проблем для которых они не предназначались, моды на функциональное программирование, притока программистов из академической среды хорошо знающих теорию групп, теорию категорий, дискретную математику и математическую логику, Лисп, Схему, Хаскелль и Coq итд итп.

Короче, const не служит для определения констант. Такие дела. Для чего он служит - это отдельный разговор. Некоторые думают что ни для чего. Я менее резок и считаю что при помощи него можно защищать инварианты класса. Если я возвращаю ссылку на std::string которая является полем моего класса я могу одеть на нее const чтобы этот стринг никто не изменил случайно по причине непонимания интерфейса класса, либо по недосмотру. Но целенаправленно либо из-за рантаймовой ошибки - изменить сможет запросто.
Стек вообще RW память, const в нем нельзя реализовать физически.
Энто кто тебе сказал?
Ну я могу конечно поставить при помощи VirtualProtect флаг Read-Only на вершину стека. Только программа при этом получит SEH исключение при первой же попытке изменить какую-то локальную переменную и перестанет работать.
const защищает данное от изменение только при доступе по его имени
Квалификатор const можно снять при помощи const_cast или C-style cast. Поскольку на практике объект всегда находится либо в хипе либо в стеке которые, в свою очередь, всегда RW и до недавшего времени даже были RWX, это всегда будет работать.
2B OR NOT(2B) = FF
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

16 дек 2015, 10:35

Этот "завал" был предложен на stackoverflow и был немедленно принят в качестве ответа. Но у Remy Lebeau нашлось куча нареканий к качеству кода и мне пришлось их фиксить несколько раз. Тебе я дал окончательный, вылизанный, вариант.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

16 дек 2015, 12:14

Сионист писал(а):const защищает данное от изменение только при доступе по его имени
Absurd писал(а):Квалификатор const можно снять при помощи const_cast или C-style cast. Поскольку на практике объект всегда находится либо в хипе либо в стеке которые, в свою очередь, всегда RW и до недавшего времени даже были RWX, это всегда будет работать.
Господа, вы оба не правы. Квалификатор const не только защищает данные от изменения при доступе по имени. И снимать константность с заведомо константного объекта с помощью const_cast является в корне неправильным подходом.

Дело в том, что объявляя данные const мы не только запрещаем их изменение, но так же сообщаем компилятору, что эти данные не будут меняться во время выполнения программы/участка кода, таким образом разрешая ему производить оптимизацию. Именно поэтому в стандарте написано, что снятие константности с заведомо константных данных и их последующая модификация ведёт к undefined behavior.

Код: Выделить всё

#include <iostream>

const int n = 10]
Скомпилируйте этот код и запустите в студии. Программист, который такое написал, ожидает вывод 10 и 5, однако, на самом деле, в качестве результата вы увидите две десятки. Компилятор прооптимизировал оба вызова std::cout и подставил везде вместо самого n его значение. А то, что n поменяли - это уже проблема глупого программиста, который не прочёл стандарт.

Если же скомпилировать и запустить это на MinGW, то вообще получите краш приложения.

Одним словом - undefined behavior.

А вот этот код будет работать адекватно на любом компиляторе:
[code=cpp]
#include <iostream>

int n = 10;

void change_param(const int& param, int value)
{
   const_cast<int&>(param) = value;
}

int main()
{
   std::cout << n << std::endl;
   change_param(n, 5);
   std::cout << n << std::endl;

   return 0;   
}
И всё потому,что мы снимаем константность, которая была наложена на объект за счёт передачи в функцию. Изначально же объект обладал не константной природой.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

16 дек 2015, 13:12

Скомпилируйте этот код и запустите в студии. Программист, который такое написал, ожидает вывод 10 и 5, однако, на самом деле, в качестве результата вы увидите две десятки. Компилятор прооптимизировал оба вызова std::cout и подставил везде вместо самого n его значение
Ну да, компилятор оптимизирует такие вещи. Но он и не-const переменную может заинлайнить если она не extern, у нее никто не берет адрес и не ставит в левую часть оператора присваивания. Кроме того, константы примитивных типов VC++ линкер помещает в секцию .CONST, а gcc сегмента .CONST не имеет и поэтому помещает разные статические стринги в сегмент .TEXT, который тоже RO. Только это не отменяет того что целочисленные константы определяются через enum, а плавающие - через constexpr. А const это никому не нужное унылое говно.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

16 дек 2015, 14:00

Ну пока не было constrexpr, это была не унылое говно, а единственное правильное решение для плавающих :) Собственно, о последнем я и не спорю. Я просто сагрился на снятие константности через const_cast или С-style cast :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1077
Зарегистрирован: 31 мар 2014, 06:18

16 дек 2015, 19:37

Господа, вы оба не правы. Квалификатор const не только защищает данные от изменения при доступе по имени.
А ничего, что значение русского предложения определяется порядком слов? Не "только защищает", а
защищает только
.
Ну я могу конечно поставить при помощи VirtualProtect флаг Read-Only на вершину стека. Только программа при этом получит SEH исключение при первой же попытке изменить какую-то локальную переменную и перестанет работать.
А каким боком флаг защиты памяти к контролю доступа на этапе компиляции?
Тут мы имеем дело с языком С++, то есть с тридцатилетней эволюцией комплексов мистера Бьорна Строуструпа, устаревших трендов, ошибочных концепций, тупиковых идей, несбывшихся надежд, шумихи начала 90-х, моды на ООП, анти-сиплюсплюсной реакции после появления Джавы, неожиданно удачного применения фичей С++ для решения проблем для которых они не предназначались, моды на функциональное программирование, притока программистов из академической среды хорошо знающих теорию групп, теорию категорий, дискретную математику и математическую логику, Лисп, Схему, Хаскелль и Coq итд итп.
Бред, кобыла отдыхает. Именованные константы были ещё в паскале.
Короче, const не служит для определения констант. Такие дела. Для чего он служит - это отдельный разговор. Некоторые думают что ни для чего. Я менее резок и считаю что при помощи него можно защищать инварианты класса. Если я возвращаю ссылку на std::string которая является полем моего класса я могу одеть на нее const чтобы этот стринг никто не изменил случайно по причине непонимания интерфейса класса, либо по недосмотру. Но целенаправленно либо из-за рантаймовой ошибки - изменить сможет запросто.
Так он и предназначен для защиты от случайного изменения, это вам не паскаль, где константность даже типизированных данных абсолютна, а значения констант всегда подставляются на этапе компиляции, из-за чего есть даже мода называть константами литералы, причём, литералы называются явными константами, а константы - именованными константами. Но если константность не отменять, то она сохраняется. Логично однако.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

16 дек 2015, 19:48

А каким боком флаг защиты памяти к контролю доступа на этапе компиляции?
Изначальная реплика звучала так: "Стек вообще RW память, const в нем нельзя реализовать физически."

Обычно когда программисты говорят "физически" они имеют в виду в виду уровень железа, т.е. аппаратную поддержку. Аппаратно памать распределяется страницами по 4К и флаг можно поставить только на целую страницу целиком.
2B OR NOT(2B) = FF
Ответить