1

On some very old code base, we have this kind of statement:

delete [i+4] v;

Where v is indeed an array and i is an integer.

This code is in VS2010 but still compiles in VS2019. Working demo

What's the meaning of this? Is it, or was it something specific to Microsoft C++?

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
Jacques
  • 301
  • 2
  • 13
  • 1
    Please show a [mre] – Alan Birtles Jul 15 '22 at 12:45
  • 1
    `delete [i+4] v;` is invalid in C++. – Jason Jul 15 '22 at 12:49
  • @AnoopRana depends on what `v` actually is. – πάντα ῥεῖ Jul 15 '22 at 12:58
  • @πάνταῥεῖ what is the case when this compiles with a C++ compiler? – Aykhan Hagverdili Jul 15 '22 at 12:59
  • @πάνταῥεῖ Yes, i have submitted a bug report [here](https://developercommunity.visualstudio.com/t/delete-2ptr-can-be-compiled-successful/10096688) – Jason Jul 15 '22 at 12:59
  • 2
    I suspect this might just be a compiler bug, you can put any value you like in there and it is just ignored, doesn't even need to be integral: https://godbolt.org/z/Y549Wz99r – Alan Birtles Jul 15 '22 at 13:00
  • 1
    I thought [this](https://stackoverflow.com/questions/381542/with-arrays-why-is-it-the-case-that-a5-5a) could apply. – πάντα ῥεῖ Jul 15 '22 at 13:02
  • @AlanBirtles Looks like it is not ignored, but rather evaluated and discarded https://godbolt.org/z/b4sWhManK – Aykhan Hagverdili Jul 15 '22 at 13:05
  • @AyxanHaqverdili well yes, I meant that the value doesn't matter, verified by debugging and stepping into `delete` and checking that the pointer passed in is the same as the original pointer – Alan Birtles Jul 15 '22 at 13:07
  • 3
    Back in the olden days (i.e., cfront), you had to include the size of the array in the array delete statement. So `int *ptr = new int[10]; delete [10] ptr;`. I vaguely recall that the size argument might have been optional in C++98, but I don't have easy access to that standard, so I might just be hallucinating. It wasn't allowed in C++03. – Pete Becker Jul 15 '22 at 13:13
  • @PeteBecker can't see it in [c++98](https://www.lirmm.fr/~ducour/Doc-objets/ISO+IEC+14882-1998.pdf) – Alan Birtles Jul 15 '22 at 13:21
  • @AlanBirtles -- thanks. It probably became optional in Cfront, because remembering the size was really annoying, and that backward-compatibility option went away with standardization. – Pete Becker Jul 15 '22 at 13:24
  • @PeteBecker I assume that the parameter was needed for correctly calling destructors on all elements as cfront those days wouldn't want to try to retrieve array size information from underlying C compiler's array headers... – Aconcagua Jul 15 '22 at 15:47
  • @Aconcagua -- that sounds right. One C++ compiler that I recall used a static lookup table to get the number of objects for `delete []`; others used the front of the allotted block. The first, of course, has serious issues for multi-threaded code, and nobody does it that way any more. – Pete Becker Jul 15 '22 at 16:16

1 Answers1

1

delete [i+4] v; where v is pointing to a dynamic array that was created using new is not valid in C++.

This seems to be a msvc bug which has been submitted here.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • *'where [...]'* – that's not exclusive to such arrays, that's *always* invalid ;) – Aconcagua Jul 15 '22 at 13:05
  • @Aconcagua I added the "where" part because [in this comment](https://stackoverflow.com/questions/72994189/strange-c-delete-statement-in-ms-c/72994414?noredirect=1#comment128923375_72994189) the user says that it depends. Also, note there was one more reason why i wrote the "where" part. Which is that in the question OP said that they have an array so i was talking in context of that. But yes it is invalid regardless. – Jason Jul 15 '22 at 13:08
  • As written it might, though, give the impression that this syntax is *only* in this situation invalid – thus I'd rather prefer wording like *'is illegal including the case where'* or similar. And actually id doesn't depend ;) – Aconcagua Jul 15 '22 at 13:23
  • @Aconcagua Note i never said that it is limited to the case where `v` is an array. I only gave an example that was already given by OP. As you can see in this [bug report](https://developercommunity.visualstudio.com/t/delete-2ptr-can-be-compiled-successful/10096688) also. – Jason Jul 15 '22 at 13:37
  • No, you didn't, you just excluded the other cases from getting a statement on – which just *might* be interpreted as not applying there, at least leaves room for such interpretation... Just a hint for a *possible* improvement, don't say either that your answer would be *incorrect* as is ;) – Aconcagua Jul 15 '22 at 13:43
  • 2
    It's only a bug if the compiler doesn't issue a diagnostic. That's the only requirement; having issued a diagnostic, the compiler is free to compile the code with an implemention-specific meaning. In this case, the compiler probably ignores the value. Passing a value is for backward compatibility with Cfront, where the value was required. – Pete Becker Jul 15 '22 at 16:18
  • 1
    @PeteBecker Ok, thanks for letting me know. I wasn't aware of the point that if the compiler issues a diagnostic in this case then it won't be considered as a bug. – Jason Jul 15 '22 at 16:26
  • @AnoopRana -- just for completeness, "a diagnostic" is any of an implementation-defined set of messages issued by the compiler. Technically, a compiler that always writes "." to the console whenever you compile code conforms to the standard if "." is in the list of implementation-defined diagnostics. Beyond that, it's just a matter of quality of implementation. – Pete Becker Jul 15 '22 at 17:11
  • @PeteBecker I see. So this does mean that msvc is not standard conformant [here](https://godbolt.org/z/Y7n3as9Pq), right? I mean in this case msvc doesn't give any diagnostic. – Jason Jul 15 '22 at 17:26
  • @AnoopRana -- looks like it. – Pete Becker Jul 15 '22 at 17:39
  • @AnoopRana Putting compiler flag `/W4` and a very clear diagnostic is issued, so the compiler is conformant: `(4): warning C4208: nonstandard extension used: delete [exp] - exp evaluated but ignored` – prapin Jul 15 '22 at 18:53