Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 30.08.15 06:19
Оценка:
Интересно, на сколько допустимо лезть на прямую в память строк, например:
    std::string mfn(MAX_PATH, 0);
    DWORD size = GetModuleFileName(NULL, &mfn[0], mfn.size());

По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?
Re: Строки - обращение на прямую
От: _Butch_  
Дата: 30.08.15 06:29
Оценка: -1 :)
Здравствуйте, dosik, Вы писали:

D>Интересно, на сколько допустимо лезть на прямую в память строк, например:

D>
D>    std::string mfn(MAX_PATH, 0);
D>    DWORD size = GetModuleFileName(NULL, &mfn[0], mfn.size());
D>


Ни насколько не допустимо. К тому же, mfn.size() в данном случае 0.


D>По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?


Это тебе кажется, что "по уму", а мне кажется, что есть стандарт языка, и в нём непрерывность гарантируется только для std::vector (и для std::string::c_str(), но этот метод возвращает константный указатель, который теоретически не обязан совпадать с собственно внутренним буфером строки).
Re: Строки - обращение на прямую
От: VTT http://vtt.to
Дата: 30.08.15 07:14
Оценка:
Здравствуйте, dosik, Вы писали:

D>Интересно, на сколько допустимо лезть на прямую в память строк, например:

D>
D>    std::string mfn(MAX_PATH, 0);
D>    DWORD size = GetModuleFileName(NULL, &mfn[0], mfn.size());
D>

D>По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?

Дело в том, что непрерывность массива символов гарантирована только для указателей, возвращаемых при вызове data() и c_str(), но при этом сами массивы доступны только для чтения. Это вроде как было сделано в древние времена чтобы позволить использовать в реализациях ::std::string всякие хитрые приемы (типа copy on write) для снижения количества копирования. Запись минуя методы string посредством хаков вроде const_cast<char *>(text.data()) или &text[0] — это прямой путь в область неопределенного поведения и удивительных багов. Так что не делайте так. Выделяйте буффер (или просто массив на стеке) и копируйте через него. И используйте GetModuleFileNameW.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[2]: Строки - обращение на прямую
От: Stanislav V. Zudin Россия  
Дата: 30.08.15 07:34
Оценка: +2
Здравствуйте, _Butch_, Вы писали:

_B_>Здравствуйте, dosik, Вы писали:


D>>Интересно, на сколько допустимо лезть на прямую в память строк, например:

D>>
D>>    std::string mfn(MAX_PATH, 0);
D>>    DWORD size = GetModuleFileName(NULL, &mfn[0], mfn.size());
D>>


_B_>Ни насколько не допустимо. К тому же, mfn.size() в данном случае 0.


не 0, а MAX_PATH (см. к-тор).

D>>По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?


_B_>Это тебе кажется, что "по уму", а мне кажется, что есть стандарт языка, и в нём непрерывность гарантируется только для std::vector (и для std::string::c_str(), но этот метод возвращает константный указатель, который теоретически не обязан совпадать с собственно внутренним буфером строки).


В '03 не не обязана выделяться непрерывно, а в '11 должна.
_____________________
С уважением,
Stanislav V. Zudin
Re[2]: Строки - обращение на прямую
От: Vlad_SP  
Дата: 30.08.15 07:45
Оценка:
Здравствуйте, VTT,

VTT>Дело в том, что непрерывность массива символов гарантирована только для указателей, возвращаемых при вызове data() и c_str(), но при этом сами массивы доступны только для чтения.


Начиная с C++11 непрерывность массива символов гарантируется (21.4.1/5).

VTT>И используйте GetModuleFileNameW.


С какой это стати??
Re[3]: Строки - обращение на прямую
От: VTT http://vtt.to
Дата: 30.08.15 08:15
Оценка: +1
Здравствуйте, Vlad_SP, Вы писали:

V_S>Начиная с C++11 непрерывность массива символов гарантируется (21.4.1/5).

Начиная с C++11 c его move семантикой и умными указателями фокусы с copy on write и совместным владением буфферами по идее больше не нужны, так что они могли бы сделать и не const data() и давать писать в буфер строки напрямую.

V_S>С какой это стати??

т.е. как с какой? не каждый путь в ANSI строчке может быть представлен
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[4]: Строки - обращение на прямую
От: Vlad_SP  
Дата: 30.08.15 08:46
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>т.е. как с какой? не каждый путь в ANSI строчке может быть представлен


Да-да-да. И будем уникодные символы запихивать в std::string?
Re[5]: Строки - обращение на прямую
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 30.08.15 09:46
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

V_S>Да-да-да. И будем уникодные символы запихивать в std::string?


После перевода в UTF-8.
Ce n'est que pour vous dire ce que je vous dis.
Re[3]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 30.08.15 10:55
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

V_S>Начиная с C++11 непрерывность массива символов гарантируется (21.4.1/5).


Ну в общем то как думалось мне. По ленился сам в стандарте посмотреть.
В любом случае сделал через буфер. Просто было интересно.

Спасибо.
Re[6]: Строки - обращение на прямую
От: -MyXa- Россия  
Дата: 30.08.15 11:14
Оценка: 5 (1)
Здравствуйте, Don Reba, Вы писали:

DR>После перевода в UTF-8.


Подкреплю твои слова вот этой ссылкой.
Если не поможет, будем действовать током... 600 Вольт (C)
Re[4]: Строки - обращение на прямую
От: Vamp Россия  
Дата: 30.08.15 13:23
Оценка:
D>В любом случае сделал через буфер. Просто было интересно.
В результате имеем лишнее копирование. В С++11 я бы копировал напрямую в string.
Да здравствует мыло душистое и веревка пушистая.
Re[5]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 30.08.15 13:47
Оценка:
Здравствуйте, Vamp, Вы писали:

V>В результате имеем лишнее копирование. В С++11 я бы копировал напрямую в string.


Согласен. Но тут еще одна подоплека: разумеется потом выполняем resize() по фактическому размеру строки, а потом желательно бы и shrink_to_fit(), чтобы не таскать с собой излишний буфер. И вот как будет себя вести shrink_to_fit() прямо не известно. Да и как-то кажется мне это дурным тоном, хотя...
Re[6]: Строки - обращение на прямую
От: VTT http://vtt.to
Дата: 30.08.15 16:21
Оценка:
Здравствуйте, dosik, Вы писали:

D>Согласен. Но тут еще одна подоплека: разумеется потом выполняем resize() по фактическому размеру строки, а потом желательно бы и shrink_to_fit(), чтобы не таскать с собой излишний буфер. И вот как будет себя вести shrink_to_fit() прямо не известно. Да и как-то кажется мне это дурным тоном, хотя...


Можно сначала узнать требуемый размер строки от GetModuleFileName и выделить память сразу под него.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[7]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 30.08.15 20:47
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Можно сначала узнать требуемый размер строки от GetModuleFileName и выделить память сразу под него.


Да вот в том то и дело, что не умеет он говорить сколько нужно... Он возвращает только столько, сколько влезло в буфер, а если буфера не хватило, то в GetLastError помещает ERROR_INSUFFICIENT_BUFFER.
Re[5]: Строки - обращение на прямую
От: Warturtle  
Дата: 31.08.15 06:29
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

V_S>Здравствуйте, VTT, Вы писали:


VTT>>т.е. как с какой? не каждый путь в ANSI строчке может быть представлен


V_S>Да-да-да. И будем уникодные символы запихивать в std::string?

std::string — это std::basic_string< char >, но существует и std::basic_string< wchar_t >.
Re[6]: Строки - обращение на прямую
От: Vlad_SP  
Дата: 31.08.15 06:49
Оценка:
Здравствуйте, Warturtle,

W>std::string — это std::basic_string< char >, но существует и std::basic_string< wchar_t >.


Спасибо, я в курсе Но ТС задал вопрос именно о std::basic_string< char >.
Re[6]: Строки - обращение на прямую
От: Vlad_SP  
Дата: 31.08.15 06:51
Оценка:
Здравствуйте, Don Reba,

гм, разве в исходном сообщении ТС было что-нибудь сказано о "переводе"?
Re[7]: Строки - обращение на прямую
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 31.08.15 07:10
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

V_S>гм, разве в исходном сообщении ТС было что-нибудь сказано о "переводе"?


Разговор об использовании API в любом случае имеет косвенное отношение к исходному сообщению.
Ce n'est que pour vous dire ce que je vous dis.
Re: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 08.09.15 17:26
Оценка:
В продолжении разговора, вот вторая реанкорнация с вкусностями С++11.
Посмотрите, нет ли тут утечки памяти:
    size_t size = MAX_PATH;
    std::unique_ptr<char[]> buff(new char[size]);
    DWORD mfn_size = GetModuleFileName(NULL, &buff[0], size);
    while (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        size *= 2;
        buff = std::unique_ptr<char[]>(new char[size]);        //Происходит ли удаление старого буфера тут?
        mfn_size = GetModuleFileName(NULL, &buff[0], size);
    }

    string path(std::move(&buff[0]));                //Действительно ли это будет оптимальней, нежели string path(&buff[0])
Re[2]: Строки - обращение на прямую
От: watchmaker  
Дата: 08.09.15 18:07
Оценка:
Здравствуйте, dosik, Вы писали:

D>        buff = std::unique_ptr<char[]>(new char[size]);        //Происходит ли удаление старого буфера тут?

Да.

D>    string path(std::move(&buff[0]));                //Действительно ли это будет оптимальней, нежели string path(&buff[0])

Оптимальней не будет, лучше выбрать вариант без std::move.
У фундаментальных типов (у указателя в данном случае) вообще нет перемещающих конструкторов — всё делается через копирование. Ну и смысла в существовании перегрузки конструктора string, принимающего r-value ссылку на указатель, тоже нет никакого по этим причинам. Так что стоит предпочесть более короткий и понятный код.
Re[3]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 08.09.15 18:16
Оценка:
Здравствуйте, watchmaker, Вы писали:

Прогнал дебагером интереса ради, действительно в первом случае после конструктора вызывается деструктор, который выполняет delete[].
Думаю что вариант с "умным" указателем даже предпочтительней чем вектор для выделения таких "одноразовых" буферов для API.
Что касается второго случая, то действительно все равно происходит копирование, что-то я тупанул. Перемещать он умеет только строки в строки, все остальное будет копировать.

Спасибо.
Re[3]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 09.09.15 07:06
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>
D>>    string path(std::move(&buff[0]));                //Действительно ли это будет оптимальней, нежели string path(&buff[0])
W>

W>Оптимальней не будет, лучше выбрать вариант без std::move.
W>У фундаментальных типов (у указателя в данном случае) вообще нет перемещающих конструкторов — всё делается через копирование. Ну и смысла в существовании перегрузки конструктора string, принимающего r-value ссылку на указатель, тоже нет никакого по этим причинам. Так что стоит предпочесть более короткий и понятный код.

И для закрепления: скажем есть функция, которая возвращает например string. Ну вот так:
string SomeFunction()
{
    string ResultString{};
    ....
    // тут мы эту сроку заполняем
    ....
    return ResultString;    //или все же надо return std::move(ResultString)?
}

    //последующий вызов например
    string a{SomeFunction()};
    string b = SomeFunction() + "qwerty";
    //и т.п.

Я так понимаю, что результаты работы функции априори возвращаются как r-value и при наличии перемещающего конструктора будет перемещен, а явно указывать это нет необходимости?
Re[2]: Строки - обращение на прямую
От: Warturtle  
Дата: 09.09.15 07:13
Оценка:
Здравствуйте, dosik, Вы писали:

D>В продолжении разговора, вот вторая реанкорнация с вкусностями С++11.

D>Посмотрите, нет ли тут утечки памяти:
D>
D>    size_t size = MAX_PATH;
D>    std::unique_ptr<char[]> buff(new char[size]);
D>    DWORD mfn_size = GetModuleFileName(NULL, &buff[0], size);
D>    while (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
D>    {
D>        size *= 2;
D>        buff = std::unique_ptr<char[]>(new char[size]);        //Происходит ли удаление старого буфера тут?
D>        mfn_size = GetModuleFileName(NULL, &buff[0], size);
D>    }

D>    string path(std::move(&buff[0]));                //Действительно ли это будет оптимальней, нежели string path(&buff[0])
D>

Во-первых, можно использовать юникодную версию функции и сразу выделить буфер в 32К. Во-вторых, unique_ptr тут, вероятно, не нужен, т.к. все это можно сделать так же коротко и с обычным вектором (vector::resize). В-третьих, функция GetModuleFileNameA не может вернуть путь длиннее MAX_PATH, поэтому нужно явно использовать GetModuleFileNameW, ну а с ней см. "во-первых" — короче говоря, вся эта возня с удвоением недостаточной ёмкости буфера вряд ли оправдана.
Re[3]: Строки - обращение на прямую
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.15 07:18
Оценка:
Здравствуйте, Warturtle, Вы писали:
W>В-третьих, функция GetModuleFileNameA не может вернуть путь длиннее MAX_PATH, поэтому нужно явно использовать GetModuleFileNameW, ну а с ней см.

А можно отсюда поподробнее, плз? Почему ANSI-версия не может вернуть путь длиннее чем MAX_PATH? Вроде ж там можно задать размер буфера равный СКОЛЬКО_ХОЧУ? Почему тогда ANSI-версия в принципе (я так понимаю) не может вернуть путь длиньше MAX_PATH?
Aml Pages Home
Re[4]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 09.09.15 07:39
Оценка:
Здравствуйте, Carc, Вы писали:

C>А можно отсюда поподробнее, плз? Почему ANSI-версия не может вернуть путь длиннее чем MAX_PATH? Вроде ж там можно задать размер буфера равный СКОЛЬКО_ХОЧУ? Почему тогда ANSI-версия в принципе (я так понимаю) не может вернуть путь длиньше MAX_PATH?

Эксперимента ради. Win 10. Вот что самое длинное у меня получилось создать:
D:\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\123456789012345678901234567890123456789012\1234567.txt
Дальше система ругается, мол слишком длинно — не пойдет.
Итого: 3 + 100 + 1 + 100 + 1 + 42 + 1 + 7 + 4 = 259, а MAX_PATH = 260 (на нолик в конце заложились)
Хотелось бы конечно документально об этом прочитать.
Re[5]: Строки - обращение на прямую
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.15 08:29
Оценка:
Здравствуйте, dosik, Вы писали:

D>Здравствуйте, Carc, Вы писали:



D>Эксперимента ради. Win 10. Вот что самое длинное у меня получилось создать:

D>D:\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\123456789012345678901234567890123456789012\1234567.txt
D>Дальше система ругается, мол слишком длинно — не пойдет.
D>Итого: 3 + 100 + 1 + 100 + 1 + 42 + 1 + 7 + 4 = 259, а MAX_PATH = 260 (на нолик в конце заложились)
D>Хотелось бы конечно документально об этом прочитать.
И я про тоже. В доке про это ограничение вроде ни слова!?!
Aml Pages Home
Re[4]: Строки - обращение на прямую
От: Warturtle  
Дата: 09.09.15 08:34
Оценка: 1 (1)
Здравствуйте, Carc, Вы писали:

C>Здравствуйте, Warturtle, Вы писали:

W>>В-третьих, функция GetModuleFileNameA не может вернуть путь длиннее MAX_PATH, поэтому нужно явно использовать GetModuleFileNameW, ну а с ней см.

C>А можно отсюда поподробнее, плз? Почему ANSI-версия не может вернуть путь длиннее чем MAX_PATH? Вроде ж там можно задать размер буфера равный СКОЛЬКО_ХОЧУ? Почему тогда ANSI-версия в принципе (я так понимаю) не может вернуть путь длиньше MAX_PATH?

Может быть я ошибаюсь, но обычно ансишные версии функций, работающие с путями ограничены длиной MAX_PATH. Для интереса попытался запустить (на Win7) exe-файл с полным именем >> MAX_PATH (на самом деле там возможно 'БукваДиска:\<MAX_PATH>') и ничего не вышло: эксплорер ругается на настройки безопасности, а CreateProcessW возвращает "The system cannot find the path specified." (GetLastError() == 3). Так что в практическом плане все еще проще.

P.S. Про ограничения в длине путей для ансишных версий и как их обходить (в юникодных версиях функций) написано в статье Naming a File.
Re[6]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 09.09.15 08:37
Оценка:
Здравствуйте, Carc, Вы писали:

C>И я про тоже. В доке про это ограничение вроде ни слова!?!

Ну плюс — минус: https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
Re[5]: Строки - обращение на прямую
От: Warturtle  
Дата: 09.09.15 08:42
Оценка:
Здравствуйте, Warturtle, Вы писали:

W>Здравствуйте, Carc, Вы писали:


C>>Здравствуйте, Warturtle, Вы писали:

W>>>В-третьих, функция GetModuleFileNameA не может вернуть путь длиннее MAX_PATH, поэтому нужно явно использовать GetModuleFileNameW, ну а с ней см.

C>>А можно отсюда поподробнее, плз? Почему ANSI-версия не может вернуть путь длиннее чем MAX_PATH? Вроде ж там можно задать размер буфера равный СКОЛЬКО_ХОЧУ? Почему тогда ANSI-версия в принципе (я так понимаю) не может вернуть путь длиньше MAX_PATH?

W>Может быть я ошибаюсь, но обычно ансишные версии функций, работающие с путями ограничены длиной MAX_PATH. Для интереса попытался запустить (на Win7) exe-файл с полным именем >> MAX_PATH (на самом деле там возможно 'БукваДиска:\<MAX_PATH>') и ничего не вышло: эксплорер ругается на настройки безопасности, а CreateProcessW возвращает "The system cannot find the path specified." (GetLastError() == 3)...
По короткому имени (8.3) такой исполняемый файл запустить можно, если суммарная длина пути, опять же, не превышает 260, но тогда и GetModuleFileName, вызванная из него, вернет короткий вариант пути.
Re[2]: Строки - обращение на прямую
От: B0FEE664  
Дата: 09.09.15 08:49
Оценка:
Здравствуйте, dosik, Вы писали:

D>
D>    string path(std::move(&buff[0]));                //Действительно ли это будет оптимальней, нежели string path(&buff[0])
D>

Оптимальней будет так:
  assert(0 <= mfn_size);
  string path(&buff[0], &buff[mfn_size]);
И каждый день — без права на ошибку...
Re[3]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 09.09.15 09:01
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Оптимальней будет так:

BFE>
BFE>  assert(0 <= mfn_size);
BFE>  string path(&buff[0], &buff[mfn_size]);
BFE>

А почему не:
    string path(&buff[0], mfn_size);

???
Re[4]: Строки - обращение на прямую
От: B0FEE664  
Дата: 09.09.15 09:19
Оценка:
Здравствуйте, dosik, Вы писали:

BFE>>Оптимальней будет так:

BFE>>
BFE>>  assert(0 <= mfn_size);
BFE>>  string path(&buff[0], &buff[mfn_size]);
BFE>>

D>А почему не:
D>
D>    string path(&buff[0], mfn_size);
D>

D>???

Так тоже можно.
И каждый день — без права на ошибку...
Re[5]: Строки - обращение на прямую
От: dosik Россия www.dosik.ru
Дата: 09.09.15 09:20
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Так тоже можно.


В общем то смысл — избавить от вычисления длинны строки?
Re[6]: Строки - обращение на прямую
От: B0FEE664  
Дата: 09.09.15 09:36
Оценка:
Здравствуйте, dosik, Вы писали:

D>В общем то смысл — избавить от вычисления длинны строки?


да.
И каждый день — без права на ошибку...
Re[5]: Строки - обращение на прямую
От: Zenden Россия  
Дата: 09.09.15 14:48
Оценка:
Здравствуйте, Warturtle, Вы писали:

W>Здравствуйте, Carc, Вы писали:


C>>Здравствуйте, Warturtle, Вы писали:

W>>>В-третьих, функция GetModuleFileNameA не может вернуть путь длиннее MAX_PATH, поэтому нужно явно использовать GetModuleFileNameW, ну а с ней см.

C>> CreateProcessW возвращает "The system cannot find the path specified." (GetLastError() == 3). Так что в практическом плане все еще проще.


Должно работать с длинными путями "\\?.." и только в 64-битном приложении под 64-битной виндой
Re: Строки - обращение на прямую
От: Zenden Россия  
Дата: 09.09.15 14:50
Оценка: -3 :))
Здравствуйте, dosik, Вы писали:

D>Интересно, на сколько допустимо лезть на прямую в память строк, например:

D>
D>    std::string mfn(MAX_PATH, 0);
D>    DWORD size = GetModuleFileName(NULL, &mfn[0], mfn.size());
D>

D>По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?

вам стоит понять, что строки стл как впрочем и многие другие классы были созданы академиками и для реального программирования пригодны чуть менее, чем никак.
Это не более, чем абстрактные строки в вакууме, с которыми ничего нельзя делать, только сидеть и радоваться, что они есть.
Отредактировано 09.09.2015 15:29 Zenden . Предыдущая версия .
Re[2]: Строки - обращение на прямую
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.15 15:09
Оценка:
Z>вам стоит понять, что строки стл как впрочем и многие другие классы были созданы академиками и для реального программирования пригодны чуть менее, чуть никак.
Z>Это не более, чем абстрактные строки в вакууме, с которыми ничего нельзя делать, только сидеть и радоваться, что они есть.
А попробуйте создать свой собственный класс строк. А вот потом поиграться с ним в плане переносимости кода Вот тогда и вспомните про академизм
Aml Pages Home
Re[6]: Строки - обращение на прямую
От: Warturtle  
Дата: 09.09.15 15:20
Оценка:
Здравствуйте, Zenden, Вы писали:

Z>Здравствуйте, Warturtle, Вы писали:


W>>Здравствуйте, Carc, Вы писали:


C>>>Здравствуйте, Warturtle, Вы писали:

W>>>>В-третьих, функция GetModuleFileNameA не может вернуть путь длиннее MAX_PATH, поэтому нужно явно использовать GetModuleFileNameW, ну а с ней см.

C>>> CreateProcessW возвращает "The system cannot find the path specified." (GetLastError() == 3). Так что в практическом плане все еще проще.


Z>Должно работать с длинными путями "\\?.." и только в 64-битном приложении под 64-битной виндой

Ну если только 64-битное. Я пробовал и с "\\?\", и с коротким (просто именем exe-файла из папки с ним): там вообще забавно было — CreateProcessW возвращал ошибку, а GetLastError() == ERROR_SUCCESS.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.