Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/40: Рейтинг темы: голосов - 40, средняя оценка - 4.60
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6816 / 2055 / 239
Регистрация: 14.12.2014
Сообщений: 4,318
Записей в блоге: 12

Передача строки в качестве параметра

07.06.2019, 16:31. Показов 8349. Ответов 66
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>
 
void test(const std::string& str)
{
    std::cout << str;
}
 
int main()
{
  test("Hello my dear friend!\n");
}
Что происходит?
Создаётся временный объект const std::string, конструктор которого принимает (и копирует в себя) const char*, вызывается функция test, затем объект уничтожается. Много лишних действий.

Можно ли сделать так, чтобы в EXE-шнике изначально хранился объект std::string, а не создавался перед вызовом функции?

p.s. В идеале – C++11, но если вариантов нет, рассмотрю что есть.

p.p.s. Интересен также вариант без создания промежуточных констант, если такое возможно, потому что, понятное, дело, можно сделать const std::string text = "Hello my dear friend!\n"; и подставлять её, но это неинтересно. Да и всё равно объект создаётся динамически.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.06.2019, 16:31
Ответы с готовыми решениями:

Передача функции в качестве параметра
Все привет. Помогите в решении следующей проблемы: есть класс XXX, один из методов которого принимает в качестве параметра указатель на...

Передача класса в качестве параметра
Здраствуйте, вообщем есть код class Main: public ExampleApplication { public: void createScene(void) { /* создаем...

Передача пути к файлу в качестве параметра через консоль
Доброго времени суток. Как в самой программе передать в качестве параметра путь к файлу? Понятное дело, что в консоли: путь до файла и...

66
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 22:44
Студворк — интернет-сервис помощи студентам
Jin X, стало ещё хуже

Добавлено через 55 секунд
Цитата Сообщение от Jin X Посмотреть сообщение
В 11 только не проканает, т.к. constexpr-функция должна состоять из одной инструкции.
Я про 17-й стандарт говорю. Хотелось бы рассчитывать хоть на что-то
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
07.06.2019, 22:47
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Это проблема, когда у тебя вызывается strlen для констант
Зачем его вызывать?

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Попробуй сделать, чтоб у макроса __FILE__ возвращалось только имя файла, без пути, всегда только в compile-time
У нас вроде бы этот дурацкий разговор вышел из-за якобы невозможности написать собственный string_view с constexpr поведением? Я вот считаю, что это можно сделать.
При чем здесь манипуляции со строками на этапе компиляции?


Вообще, давай начнем с того, что ты расскажешь чем ты компилируешь вообще?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 22:52
Цитата Сообщение от DrOffset Посмотреть сообщение
Я же привел версию выше. Где ж оно одинаковое? Там внутри __builtin_strlen используется.
Она что, возвращает константу, или появились встроенные compile-time-функции? Подставь в свою функцию этот __builtin_strlen и получишь цикл

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
У нас вроде бы этот дурацкий разговор вышел из-за якобы невозможности написать собственный string_view с constexpr поведением? Я вот считаю, что это можно сделать.
При чем здесь манипуляции со строками на этапе компиляции?
При том, что когда ты пишешь строку "12345" ожидаешь, что компилятор подставит размер 5, а не вызовет strlen

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Вообще, давай начнем с того, что ты расскажешь чем ты компилируешь вообще?
Тот мой пример - на gcc 9.1, https://godbolt.org/z/n1vmg-
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
07.06.2019, 23:01
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Тот мой пример - на gcc 9.1
Ну и где он вызывает strlen?
Вот твой код показывает, что библиотечный char_traits не приводит к циклу. Ну так и реализуй свой string_view с помощью библиотечного char_traits, даже если предположить, что компилятор действительно по-разному компилирует код (хотя это нифига не так). В чем проблема-то?

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Подставь в свою функцию этот __builtin_strlen и получишь цикл
Подставил: https://godbolt.org/z/oV67Fm
Где цикл?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 23:06
Цитата Сообщение от DrOffset Посмотреть сообщение
Подставил: https://godbolt.org/z/oV67Fm
Где цикл?
Ага, значит __builtin_strlen он тоже по-другому компилирует.
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот твой код показывает, что библиотечный char_traits не приводит к циклу. Ну так и реализуй свой string_view с помощью библиотечного char_traits, даже если предположить, что компилятор действительно по-разному компилирует код (хотя это нифига не так). В чем проблема-то?
Проблема в том, что в общем случае, я не могу написать свою функцию, которая будет выполняться в compile-time. Всё вышесказанное только подтверждает это.
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6816 / 2055 / 239
Регистрация: 14.12.2014
Сообщений: 4,318
Записей в блоге: 12
07.06.2019, 23:08  [ТС]
Я сейчас немного потестил. В зависимости от компилятора и от разных настроек -O при использовании strlen где-то подставляется число, а где-то вызывается strlen. Аналогично и с while. Только while написан очень неоптимально. Но while чаще превращается в число, чем strlen. Вот такая ерундень. А юзать __builtin_strlen, думаю, не стоит вообще, т.к. это вне стандарта.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
07.06.2019, 23:12
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ага, значит __builtin_strlen он тоже по-другому компилирует.
Что значит по-другому? Речь о чем шла? Что код одинаковый, якобы. Но он разный, поэтому и поведение разное. Выровняли код, и поведение тоже выровнялось.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Проблема в том, что в общем случае, я не могу написать свою функцию, которая будет выполняться в compile-time. Всё вышесказанное только подтверждает это.
Не нужно просто пихать заведомо не-compile time функции и все будет нормально.
В данном случае всю малину портит printf.

А в 9.1 похоже просто какой-то баг. Потому что, например, GCC 8.1 вот на таком коде никаких циклов не делает: https://godbolt.org/z/NVuiSz. А 9.1 - делает.

Добавлено через 37 секунд
Цитата Сообщение от Jin X Посмотреть сообщение
А юзать __builtin_strlen, думаю, не стоит вообще, т.к. это вне стандарта.
Я его юзать не предлагал. Просто хотел показать, что библиотечный код отличается.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 23:13
Цитата Сообщение от Jin X Посмотреть сообщение
Я сейчас немного потестил. В зависимости от компилятора и от разных настроек -O при использовании strlen где-то подставляется число, а где-то вызывается strlen. Аналогично и с while. Только while написан очень неоптимально. Но while чаще превращается в число, чем strlen. Вот такая ерундень. А юзать __builtin_strlen, думаю, не стоит вообще, т.к. это вне стандарта.
Там вопрос стоит - стоит ли рассчитывать на constexpr или нет. Строки - это тупо самый простой пример. Проблема, в том, что твой код компилируется по другому, чем стандартный. А должен также.
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6816 / 2055 / 239
Регистрация: 14.12.2014
Сообщений: 4,318
Записей в блоге: 12
07.06.2019, 23:13  [ТС]
https://godbolt.org/z/pbWriz
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 23:17
Цитата Сообщение от DrOffset Посмотреть сообщение
Что значит по-другому? Речь о чем шла? Что код одинаковый, якобы. Но он разный, поэтому и поведение разное. Выровняли код, и поведение тоже выровнялось.
__builtin_strlen - это что вообще такое? Ключевое слово? Почему никто не знает о нём? Как мне сделать такие же ключевые слова?

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Не нужно просто пихать заведомо не-compile time функции и все будет нормально.
В данном случае всю малину портит printf.
printf там вообще не при делах. Он вызывается только чтоб компилятор не заоптимизировал код до нуля
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
07.06.2019, 23:17
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ключевое слово? Почему никто не знает о нём? Как мне сделать такие же ключевые слова?
Цитата Сообщение от DrOffset Посмотреть сообщение
Я его юзать не предлагал. Просто хотел показать, что библиотечный код отличается.
;-)
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 23:22
Цитата Сообщение от DrOffset Посмотреть сообщение
его юзать не предлагал. Просто хотел показать, что библиотечный код отличается.
Нудануда, у них имена функций другие. Назвал бы я свою функцию __builtin_strlen - всё б залетало.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
07.06.2019, 23:28
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Нудануда, у них имена функций другие. Назвал бы я свою функцию __builtin_strlen - всё б залетало.
О чем это вообще?
Чего ты передергиваешь?

__builtin_strlen - это интринсик компилятора, в специализации char_traits<char> именно он используется в реализации length(), а не цикл. Поэтому, когда разработчики в GCC 9.1 посадили баг, который проявляется при использовании циклов в constexpr - пользовательский код сломался, а библиотечный - нет. Потому как раз, что явного цикла там нет.
Поэтому я говорю, что компилятор не собирает код по-разному. Если бы в библиотечной реализации тоже был цикл, библиотечная реализация тоже бы сломалась из-за этого бага.

Я там выше ссылку дал на 8.1. Чего ты ее проигнорировал-то?
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6816 / 2055 / 239
Регистрация: 14.12.2014
Сообщений: 4,318
Записей в блоге: 12
07.06.2019, 23:32  [ТС]
Вот, держите: https://godbolt.org/z/cbbsjK
Всё он одинаково компилит, у вас просто constant_string_p вылетело из кода куда-то (в char_traits.h он называется __constant_string_p)
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 23:46
Цитата Сообщение от DrOffset Посмотреть сообщение
Я там выше ссылку дал на 8.1. Чего ты ее проигнорировал-то?
А ты погляди повнимательнее на мой пример. Там четыре вызова length. Три из них в compile-time, один в runtimе. Объясни мне это хоть интрициниками, хоть без.

Добавлено через 2 минуты
DrOffset, ну и что там насчёт __FILE__, сможешь сделать?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
08.06.2019, 00:04
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Объясни мне это хоть интрициниками, хоть без.
Я это объясняю багом в свежем GCC.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
ну и что там насчёт __FILE__, сможешь сделать?
Не вижу смысла здесь это делать. К изначальному вопросу это не относится.
Хочешь - создай тему об этом.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
08.06.2019, 00:08
Цитата Сообщение от DrOffset Посмотреть сообщение
Я это объясняю багом в свежем GCC.
Это не в свежем, во всех

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Не вижу смысла здесь это делать. К изначальному вопросу это не относится.
Хочешь - создай тему об этом.
Зачем?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
08.06.2019, 00:22
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Это не в свежем, во всех
Может и во всех. Я засабмитил, посмотрим.
Вообще не знаю как относиться к твоему примеру, учитывая, что clang даже отказывается его компилировать.
Возможно GCC перестает считать строку-параметр функции Test как contsexpr из-за того, что сама функция перестает быть constexpr (из-за printf). Внутри библиотечной реализации есть builtin-помощники, которые видимо создают дополнительный критерий в случае, если строка таки на самом деле constexpr. А вот с пользовательской реализацией уже не работает - идет по runtime варианту. В чистом constexpr контексте баг проявляется только на 9.1 и выше, я показал это в своем примере. Учитывая, что изначальная цель получить constexpr вариант, рассматривать вариант с не-constexpr из-за посторонних runtime функций внутри (даже если там баг) в этой теме оффтоп.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Зачем?
Ну если ты хочешь обсудить постороннюю тему, то лучше создать для этого отдельную ветку.
Мы и так тут отклонились сильно.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
08.06.2019, 00:26
Цитата Сообщение от DrOffset Посмотреть сообщение
Возможно GCC перестает считать строку-параметр функции Test как contsexpr из-за того, что сама функция перестает быть constexpr (из-за printf). Внутри библиотечной реализации есть builtin-помощники,
Убери там constexpr и всё, там она совершенно не нужна, просто не заметил

Добавлено через 1 минуту
Проблема там в CTest::length
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
08.06.2019, 13:09
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Убери там constexpr и всё
Если его убрать, то runtime-поведение будет закономерным для пользовательской функции. Потому что без constexpr функция Test - это обычная функция с runtime-параметром - такой параметр поданный на вход constexpr-функции выводит ее из constexpr-контекста согласно правилам языка.
Библиотечный шаблон продолжает работать в compile-time вопреки этому уже засчет механизмов компилятора: constant_string_p и __builtin_strlen, которые используются в реализации. Я об этом уже говорил. Конечно, GCC, мог бы быть и поумнее, и скомпилировать этот код одинаково, но его поведение вполне согласуется с правилами языка.
А вот та ситуация, которую я привел, явно ошибочная. Посмотрим что ответят разработчики.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Проблема там в CTest::length
Да нет в ней никакой проблемы. Она написана корректно и будет являться constexpr-функцией при условии, что на вход ей будет подано constexpr-выражение. В твоем коде это не так, поэтому получаем runtime. В моем коде - это так, но GCC 9.1 все равно делает runtime и это скорее всего баг.

Не знаю что еще добавить. По-моему тут все понятно-прозрачно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.06.2019, 13:09

Передача строки в качестве аргумента потоку
Создаю массив handle'ов HANDLE threads; Есть массив, состоящий из 5 символов &quot;ABCDE&quot; char symb; Создаю потоки...

Передача функции в качестве параметра
Как передать функцию с параметрами в transform? Т.е., например, мне надо из каждого числа вектора вычесть число k с помощью transform'а,...

Передача файла в качестве параметра
Как, в качестве параметра, передать функции файл и структуру??? Добавлено через 1 час 1 минуту Разве никто не знает???

Передача функции в качестве параметра
#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; double f(double x) { return (2*x*x)-(exp(x)); double...

Передача CString в качестве параметра функции
Добрый всем вечер! Мучает один вопрос, на который не могу найти ответ. Как наилучшим образом передавать объект класса CString в...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал (мат мет мод 29)
anaschu 23.06.2026
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал Материалы для обсуждения с МГСУ · 2026 Рисунки внутри приложенного ворд файла. Что за. . .
28. Конкретное развертывание плана номер 1 из поста номер 27
anaschu 22.06.2026
Можно ли из модели получить конкретные строительные требования? Честно — напрямую из текущей модели такие ответы не получить. Но цепочка логики есть, и она не такая длинная. Где разрыв . . .
27. Планы на разработку функциональных требований к строительству внутри модели пищеблока (или не только его?)
anaschu 22.06.2026
Что уже реализовано и даёт конфликты «бесплатно» Самый простой конфликт уже работает — конфликт за ресурс-работника. Заданий больше, чем доступных поваров → очередь в queue1. Это прямое отражение. . .
26. мед мат модель.Какие типы конфликтов функциональных требований можно рассчитать через ДЕС-моделирование (СМО) в AnyLogic?
anaschu 22.06.2026
Что ДЕС/ СМО умеет считать напрямую: Конфликты за ресурсы (очереди, узкие места). Несколько типов агентов (повара, учителя, рабочие, пациенты) претендуют на один ресурс (лифт, вход, коридор,. . .
25 модель здравосохранения и функциональных требований к пищеблоку: конфликты функциональных требований.
anaschu 22.06.2026
Есть ли данные о том, какие функциональные/ эксплуатационные требования или их сочетания труднее всего учитывать при проектировании зданий? Да, такие данные есть, и они хорошо описаны и в российской,. . .
Remote Connection Manager
DevAlt 21.06.2026
Написал для себя небольшую прилагу: https:/ / github. com/ altbodhi/ ReConMan По итогу пришел к мысли, что DU не дружат с существующими технологиями. От сериализации до отображения в реляционную. . .
Администрация Хабра удаляет новые энергоэфективные алгоритмы, которые не западной школы кода, и вовсе никак не сгенерированы
Hrethgir 20.06.2026
Делается это, как замечено, при правках - при объявлении концептуальных отличий в алгоримах. Делается это, по линейке событий - после дополнения публикации основными отличиями от основных западных. . .
Процесс ориентированная диалектика (не новость - просто системное обновление, философия).
Hrethgir 20.06.2026
Однажды один участник в своём блоге, на этом форуме, сделал запись "О языках замолвите слово". Понимая, что язык - важная вещь, я решил хорошо подумать, прежде чем сказать, и сказал то, что вы видите. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru