Why does an empty string literal in a multidimensional array decay to a null pointer?
Asked Answered
A

2

8

I want to define a multidimensional C-string array, initialized by several string literals. In C I would do the following:

#include <stdio.h>

const char *strArr[2][1] = { {"foo"}, {""}};

int main(void) {
    printf("%p\t%p\n", strArr[0][0], strArr[1][0]);
    return 0;
}

Compiling with gcc -std=c18 -pedantic test.c and executing results in:

$ ./a.out 
0x55d95410f004  0x55d95410f008

As I expect, the empty string literal in strArr[1][0] decays to a valid pointer.


However, when I try the same code in C++:

#include <cstdio>

const char *strArr[2][1] = { {"foo"}, {""}};

int main(void) {
    printf("%p\t%p\n", strArr[0][0], strArr[1][0]);
    return 0;
}

Compiling with g++ -std=c++17 -pedantic test.cpp and executing results in:

$ ./a.out 
0x55c61494d004  (nil)

Here, the empty string literal in strArr[1][0] decays to a null pointer. Why does this happen in C++?


In the C++17 standard, I see the following in 5.13.5 paragraph 16:

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (6.7).

This seems to indictate that an empty string literal, being an ordinary string literal, should have static storage duration. So why would an empty string literal decay to a null pointer?

Aggravation answered 27/11, 2019 at 18:36 Comment(20)
Why use a C-style array in the first place? Why not std::array?Eudoxia
@WeatherVane that should be an answerLyford
Which langauge are you asking about?Ski
I'm asking about C++, since the standard doesn't seem to agree with the result of my code.Aggravation
@Vilhelm Gray I can not reproduce the problem.Delanie
I misread the code, thinking it was a [2][2] array, so mybad deleted comments and answer. What's the point of a [2][1] array anyway?Ski
@WeatherVane Sorry, that's my fault as well since I had a typo in the original version. I'm using [2][1] for the sake of illustration, not for any practical reason: it's a forced example to illustrate the issue.Aggravation
Which compiler and compiler version are you using specifically?Gman
g++ (Gentoo 9.2.0-r2 p3) 9.2.0Aggravation
I cannot reproduce this with clang 8.0, nor gcc 8.3, nor vc14, fwiw (the latter isn't 17 compliant, but wth; why not try).Disarray
How is a nullptr not a valid pointer to an empty string literal? Seems reasonable to me.Infecund
@Infecund an empty string has one character: the terminator. When you print it, it outputs a valid nothing.Ski
This is probably just a GCC 9 regression. You should report it and see what they say.Euh
@Infecund 5.13.5 paragraph 14 states that a string literal will have at least \0 appended.Aggravation
tio.run/…Ginny
g++ does this, clang doesn't: gcc.godbolt.org/z/XkZcVy Looks like a g++ bug.Maillot
I think everyone is right, this looks like a regression in g++ 9 since it's not there in previous versions. I'll try reporting to the g++ developers and see what they say.Aggravation
I'm late to the party, but please keep us informed of what they say. :)Allowedly
@VilhelmGray: Can you post a link to the bug report? (gcc.gnu.org/bugzilla is the bug tracker for gcc/g++.)Manchukuo
@KeithThompson Account creation on the GCC bugzilla site is restricted, so I submitted an email request that will hopefully be fulfilled by tomorrow. For now, I have opened a bug report on Gentoo: bugs.gentoo.org/701364Aggravation
A
2

This behavior is not correct, and in this case is the result of a regression in GCC: https://gcc.gnu.org/PR90947

The regression has been fixed for GCC version 9.3 and should hopefully make it back to the earlier versions affected as well.

Aggravation answered 29/11, 2019 at 16:49 Comment(0)
D
0

There is no such decay ; the output you observed is a compiler bug.

(Yes this is a short answer but there is nothing else to add).

Disturb answered 28/11, 2019 at 0:14 Comment(1)
From the comments on the question, it's a regression in g++ 9, reported on Gentoo: bugs.gentoo.org/701364Manchukuo

© 2022 - 2024 — McMap. All rights reserved.