Почему позволяют конкатенацию строковых литералов?

Я был недавно укушен тонкой ошибкой.

char ** int2str = {
   "zero", // 0
   "one",  // 1
   "two"   // 2
   "three",// 3
   nullptr };

assert( int2str[1] == std::string("one") ); // passes
assert( int2str[2] == std::string("two") ); // fails

Если у Вас будут богоподобные полномочия обзора кода, то Вы заметите, что я забыл , после "two".

После значительного усилия найти, что ошибка я должен спросить, почему кто-либо когда-либо хотел бы это поведение?

Я вижу, как это могло бы быть полезно для макро-волшебства, но затем почему это - "функция" на современном языке как Python?

Вы когда-либо использовали конкатенацию строкового литерала в производственном коде?

11
задан Deduplicator 13 October 2015 в 17:03
поделиться

7 ответов

Я не уверен насчет других языков программирования, но, например, C # не позволяет вам этого делать (и я думаю, что это хорошо). Насколько я могу судить, большинство примеров, показывающих, почему это полезно в C ++, все равно работали бы, если бы вы могли использовать какой-нибудь специальный оператор для конкатенации строк:

string someGlobalString = "very long " +
                          "so broken " +
                          "onto multiple " +
                          "lines"; 

Это может быть не так удобно, но, безусловно, безопаснее. В вашем мотивирующем примере код будет недействительным, если вы не добавите , для разделения элементов или + для объединения строк ...

2
ответ дан 3 December 2019 в 00:51
поделиться

Чтобы можно было разбивать длинные строковые литералы по строкам.

И да, я видел это в производственном коде.

1
ответ дан 3 December 2019 в 00:51
поделиться

У меня конечно есть как на C, так и на C ++. Навскидку, я не вижу особой взаимосвязи между его полезностью и тем, насколько «современный» язык.

0
ответ дан 3 December 2019 в 00:51
поделиться

Это отличная функция, которая позволяет вам комбинировать строки препроцессора с вашими строками.

// Here we define the correct printf modifier for time_t
#ifdef TIME_T_LONG
    #define TIME_T_MOD "l"
#elif defined(TIME_T_LONG_LONG)
    #define TIME_T_MOD "ll"
#else
    #define TIME_T_MOD ""
#endif

// And he we merge the modifier into the rest of our format string
printf("time is %" TIME_T_MOD "u\n", time(0));
17
ответ дан 3 December 2019 в 00:51
поделиться

Конечно, это простой способ улучшить внешний вид вашего кода:

char *someGlobalString = "very long "
                         "so broken "
                         "onto multiple "
                         "lines";

Однако лучшая причина - в использовании странных форматов printf, например, принуждения типов:

uint64_t num = 5;
printf("Here is a number:  %"PRIX64", what do you think of that?", num);

Есть куча тех, которые определены, и они могут пригодиться, если у вас есть требования к размеру шрифта. Ознакомьтесь со всеми по этой ссылке . Несколько примеров:

PRIo8 PRIoLEAST16 PRIoFAST32 PRIoMAX PRIoPTR
22
ответ дан 3 December 2019 в 00:51
поделиться

Случаи, когда это может быть полезно:

  • Генерация строк, включая компоненты, определенные препроцессором (это, пожалуй, самый большой вариант использования в C, и я вижу его очень и очень часто).
  • Разделение строковых констант на несколько строк

Чтобы дать более конкретный пример для первого:

// in version.h
#define MYPROG_NAME "FOO"
#define MYPROG_VERSION "0.1.2"

// in main.c
puts("Welcome to " MYPROG_NAME " version " MYPROG_VERSION ".");
5
ответ дан 3 December 2019 в 00:51
поделиться

Из справочника по лексическому анализу Python, раздел 2.4.2:

Эту функцию можно использовать для уменьшения количества необходимых обратных косых черт, чтобы удобно разделить длинные строки на длинные {{ 1}} строк или даже для добавления комментариев к частям строк

http://docs.python.org/reference/lexical_analysis.html

3
ответ дан 3 December 2019 в 00:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: