Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.69/29: Рейтинг темы: голосов - 29, средняя оценка - 4.69
Эксперт WindowsАвтор FAQ
17783 / 7519 / 888
Регистрация: 25.12.2011
Сообщений: 11,287
Записей в блоге: 16
1

Значение типа "const wchar_t *" нельзя присвоить сущности типа "LPWSTR"

30.11.2018, 16:03. Показов 6074. Ответов 14
Метки нет (Все метки)

Здравствуйте!

Что нужно поменять в настройках проекта, чтобы исправить эту ошибку?

значение типа "const wchar_t *" нельзя присвоить сущности типа "LPWSTR"
(последняя строка)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <cstdio>
#include <iostream>
#include <tchar.h>
#include <windows.h>
#include <tlhelp32.h>
#include <userenv.h>
 
#pragma comment(lib, "Userenv.lib")
 
...
 
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
si.lpDesktop = _T("WinSta0\\Default");
Проект уже настроен на набор символов Юникода.
В одном проекте это собирается, а в другом нет. При этом код полностью идентичный.

Спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.11.2018, 16:03
Ответы с готовыми решениями:

Значение типа "char *" нельзя присвоить сущности типа "LPWSTR"
как исправить эту ошибку значение типа &quot;char *&quot; нельзя присвоить сущности типа &quot;LPWSTR&quot;

Значение типа "char *" нельзя присвоить сущности типа "LPWSTR"
значение типа &quot;char *&quot; нельзя присвоить сущности типа &quot;LPWSTR&quot; void AddColToListView(char...

Error: значение типа "const char" нельзя присвоить сущности типа "double"
#include &lt;iostream&gt; #include &lt;iomanip&gt;// using namespace std; void main(void) { const int...

Как исправить ошибку: Значение типа "const char *" нельзя присвоить сущности типа "char *"?
#include &lt;conio.h&gt; #include &lt;iostream&gt; using namespace std; struct Car_Specifications {...

14
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
30.11.2018, 16:14 2
Dragokas, Значение типа "char *" нельзя присвоить сущности типа "LPWSTR"
Смотрите последние посты, мб поможет
0
Эксперт С++
1605 / 936 / 778
Регистрация: 06.02.2016
Сообщений: 2,425
Записей в блоге: 30
30.11.2018, 16:24 3
Dragokas, Попробуйте
C++
1
si.lpDesktop = _T(L"WinSta0\\Default");
0
Эксперт WindowsАвтор FAQ
17783 / 7519 / 888
Регистрация: 25.12.2011
Сообщений: 11,287
Записей в блоге: 16
30.11.2018, 18:07  [ТС] 4
Peoples, попробовать то я могу, но зачем так извращаться, если проблема в каких-то неверных настройках проекта.

Добавлено через 3 минуты
Azazel-San, повторюсь, студия одна и таже VS 2017. Код один и тот же. Один файл main.cpp
Но, в одном проекте собирается удачно, в другом нет. И даже инфа на основных вкладках свойств проектов выглядит идентичной.
Если нужно могу скинуть проекты целиком.
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
30.11.2018, 18:17 5
Dragokas, ну, могу предположить что не все настройки идентичны тогда, у вас ошибка, типо, вы пытаетесь объекту LPWSTR присвоить LPCWSTR, вы хотели исправить ошибку в коде или в настройках проекта, если второе, то заголовок темы вы подобрали не тот
0
Эксперт WindowsАвтор FAQ
17783 / 7519 / 888
Регистрация: 25.12.2011
Сообщений: 11,287
Записей в блоге: 16
30.11.2018, 18:45  [ТС] 6
Вообще, я хотел узнать подробное объяснение, потому что плохо шарю в указателях.
Т.е., как я понимаю, здесь

LPWSTR lpDesktop - (LP) указатель на (WSTR) юникодную строку.
"WinSta0\\Default" - константная строка.
_T - макрос, указывающий, что при настройках проекта на набор символов "Юникод", строка будет интерпретироваться как юникодная.
Соответственно присвоение невозможно так как ожидается буфер с выделенной памятью с доступом Read/Write, а я подаю ReadOnly (т.е. константную). Правильно ли я понимаю?

И если да, то почему вы советуете преобразование в (LPTSTR)_T("WinSta0\\Default") в той теме. Разве строка от этого перестанет быть константной?

=======

Вообщем, разобрался сам (хотя и хотелось бы получить ответы на вопросы выше).

В проекте, где возникала эта ошибка, стояла опция:

Режим совместимости: (Да) /permissive-
Убрал ее, и всё собралось.

Ещё стояла:
Проверки SDL: (Да) /sdl
Но это влияло только на превращение предупреждений в ошибки вида:
'wcscpy': This function or variable may be unsafe. Consider using wcscpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
1
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
30.11.2018, 18:51 7
Цитата Сообщение от Dragokas Посмотреть сообщение
Разве строка от этого перестанет быть константной?
Соглашусь, возможно это и не лучший вариант но да, она перестанет быть константой, "Сишное" преобразование типов это неявное применение целого комплекта кастов, например static + const
0
15352 / 8300 / 2014
Регистрация: 30.01.2014
Сообщений: 14,173
30.11.2018, 23:46 8
Цитата Сообщение от Azazel-San Посмотреть сообщение
но да, она перестанет быть константой
Нет, не перестанет.
Снятие константности с указателя на константу не делает константу неконстантой. Так что строка останется константной, даже при наличии таких указателей на нее. Более того, если мы попробуем изменить через такой указатель константную строку, то выйдем на UB.

Добавлено через 3 минуты
Цитата Сообщение от Dragokas Посмотреть сообщение
Убрал ее, и всё собралось.
В Си-шных, особенно старых интерфейсах, такое довольно часто можно наблюдать. Функция, или в данном случае структура, получает указатель на неконстанту, но при этом гарантируется, что не будет меняться через него содержимое объекта. Соглашение на уровне договоренностей, и, может быть, описания в документации. Так что, если нам такие гарантии даны, то можно сделать явный каст.
1
Эксперт WindowsАвтор FAQ
17783 / 7519 / 888
Регистрация: 25.12.2011
Сообщений: 11,287
Записей в блоге: 16
01.12.2018, 00:22  [ТС] 9
Спасибо. Наконец-то пришло понимание.

Цитата Сообщение от DrOffset Посмотреть сообщение
но при этом гарантируется, что не будет меняться через него содержимое объекта
А кем именно гарантируется? Документацией по этой функции?
0
15352 / 8300 / 2014
Регистрация: 30.01.2014
Сообщений: 14,173
01.12.2018, 01:03 10
Лучший ответ Сообщение было отмечено Dragokas как решение

Решение

Цитата Сообщение от Dragokas Посмотреть сообщение
А кем именно гарантируется? Документацией по этой функции?
Ну так это зависит от ситуации. В том числе и документацией или словами разработчика, или просмотром тобой исходников, чтобы убедиться в этом.
Собственно const - это автоматизированный контроль этих гарантий компилятором. Разработчик поставил const - значит возложил обязанность контроля на компилятор, не поставил - значит возложил эту обязанность на программиста. Естественно лучше, когда автоматизированный инструмент проверяет для тебя контракты, я думаю, с этим никто не будет спорить. Но реальность такова, что иногда приходится убеждать инструмент, что ты лучше знаешь, что делаешь

Однако именно в данном случае, мне кажется, нет нужды ломать типизацию. Я бы сделал так:
C++
1
2
3
4
5
static TCHAR lpDesktop[] = _T("WinSta0\\Default");
 
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
si.lpDesktop = lpDesktop;
1
Эксперт WindowsАвтор FAQ
17783 / 7519 / 888
Регистрация: 25.12.2011
Сообщений: 11,287
Записей в блоге: 16
01.12.2018, 01:10  [ТС] 11
Спасибо за разъяснения и хороший пример.
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
01.12.2018, 01:17 12
Цитата Сообщение от DrOffset Посмотреть сообщение
Снятие константности с указателя на константу не делает константу неконстантой.
Да, точно, все верно, это же указатели, спасибо за поправку.
Цитата Сообщение от DrOffset Посмотреть сообщение
Более того, если мы попробуем изменить через такой указатель константную строку, то выйдем на UB.
Ну, я говорил что это не лучший вариант Хотя вспоминая для чего она используется, вроде такое не должно случится, конечно если мы сами на это не наступим.
Цитата Сообщение от DrOffset Посмотреть сообщение
Однако именно в данном случае, мне кажется, нет нужды ломать типизацию. Я бы сделал так:
Еще вроде есть вариант с wcscpy (надеюсь правильно написал)?
0
15352 / 8300 / 2014
Регистрация: 30.01.2014
Сообщений: 14,173
01.12.2018, 01:27 13
Цитата Сообщение от Dragokas Посмотреть сообщение
Документацией по этой функции?
Для начала знать бы по какой.
Но если речь, например, о CreateProcess, то там нигде явно не указано, что lpDesktop будет изменяться. Также явно указано, что все значения из этой структуры копируются без изменений в создаваемый процесс. Также по смыслу и описанию этого поля нигде не предполагается, что оно предназначено для записи. Если же какое-то из параметров функции может быть изменено изнутри, то об этом явно написано, например, как написано про lpCommandLine. Т.е. можно сделать вывод, что некоторое обещание есть, но до гарантии не дотягивает.
В общем, я предлагаю все-таки не ломать типизацию, тем более это решение здесь никак не повлияет негативно - зато код будет без подозрительных кастов (или опасных вседозволяющих флагов компилятора).

Добавлено через 54 секунды
Цитата Сообщение от Azazel-San Посмотреть сообщение
Еще вроде есть вариант с wcscpy (надеюсь правильно написал)?
Она тут не подойдет. Там же в структуре просто указатель, а не буфер.
1
Эксперт WindowsАвтор FAQ
17783 / 7519 / 888
Регистрация: 25.12.2011
Сообщений: 11,287
Записей в блоге: 16
01.12.2018, 01:44  [ТС] 14
Цитата Сообщение от DrOffset Посмотреть сообщение
Она тут не подойдет. Там же в структуре просто указатель, а не буфер.
Ну я думаю, можно было бы сделать так:

C++
1
2
3
4
5
6
7
8
BOOL foo(PCTSTR pszDesktop)
{
    ...
    static TCHAR lpszDesktop[MAX_PATH] = { 0 };
    wcscpy(lpszDesktop, pszDesktop);
    ...
    si.lpDesktop = lpszDesktop;
}
(если бы задача стояла подавать на вход произвольную константную строку)

static у вас, я так понимаю, чтобы после выполнения CreateProcess и копирования структуры в системную область, указатель продолжал указывать на валидную память даже после выхода из процедуры. Хотя как по мне такое актуально только для каких-нибудь асинхронных функций, где структура может не успеть скопироваться. В конкретном же случае, структура будет копироваться вместе с данным (не только указатель), т.к. нормальная работа порожденного процесса гарантируется и после завершения родительского.
0
15352 / 8300 / 2014
Регистрация: 30.01.2014
Сообщений: 14,173
01.12.2018, 02:05 15
Цитата Сообщение от Dragokas Посмотреть сообщение
В конкретном же случае, структура будет копироваться вместе с данным (не только указатель), т.к. нормальная работа порожденного процесса гарантируется и после завершения родительского.
Да, конечно.
static там не для этого, а просто чтобы постоянно не копировать строку в массив на стеке, в случае многократного вызова этой функции, где будет этот код. Если у вас свои пожелания на счет этого, то я разумеется ничего не навязываю.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.12.2018, 02:05

Ошибка: значение типа "const char*" нельзя присвоить сущности типа "char*"
Появилось в 17 студии, как это исправить?

Ошибка "значение типа "const char [81]" нельзя использовать для инициализации сущности типа "const unsigned char [61]"
Прошу помощи, так как раньше прога работала, сейчас решил вернуться и выдает ошибку: #pragma once...

Значение типа "const char" нельзя присвоить сущности типа "char*"
Добрый день. Разбираю классы и столкнулся вот с чем. В одной версии visual studio данный код...

Ошибка: значение типа "const char *" нельзя использовать для инициализации сущности типа "char *" (строка 8)
#include &lt;iostream&gt; using namespace std; int main() { int number = 0; char *result; char...

Динамические массивы: значение типа "int *" нельзя присвоить сущности типа "int"
МАССИВЫ: динамические массива ОШИБКА:значение типа &quot;int *&quot; нельзя присвоить сущности типа &quot;int&quot; ...

Ошибка преобразования: значение типа "float *" нельзя присвоить сущности типа "float"
Помогите исправить.Значение типа &quot;float *&quot; нельзя присвоить сущности типа float void Mode2() {...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru