public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Invalid use of 'void'
@ 2020-05-18 10:30 Игорь Горлов
  2020-05-18 15:03 ` Niklas Gürtler
  0 siblings, 1 reply; 6+ messages in thread
From: Игорь Горлов @ 2020-05-18 10:30 UTC (permalink / raw)
  To: gcc-help

Hi all.

I have an issue when compiling a simple console program on Windows (Msys2).
First, let's consider the program itself:

void.cpp:
#include <cstddef>
#include <cstdlib>
#include <iostream>
int main()
{
// Getting any 2 valid void pointers
void* p1=std::malloc(32);
void* p2=std::malloc(64);
if(p1==nullptr||p2==nullptr)
{
std::cout << "Error: failed to get 2 valid void pointers" << std::endl;
return 1;
}
// Now trying to calculate the difference between these pointers
std::ptrdiff_t difference=p2-p1;
std::cout << "The difference is " << difference << std::endl;
return 0;
}

This program is not compatible with the C++17 standard. However, we can compile it with -std=gnu++17 (C++17 with GNU extensions), because one of that extensions permits calculations on void pointers. Additionally, we append -Wno-pointer-arith to suppress the related warning. So, our command line looks like this:

# g++ void.cpp -std=gnu++17 -Wno-pointer-arith -o void.exe

GCC responds:
void.cpp: In function 'int main()':
void.cpp:16:30: error: invalid use of 'void'
   16 | std::ptrdiff_t difference=p2-p1;
      |                              ^~

What am I doing wrong?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Invalid use of 'void'
  2020-05-18 10:30 Invalid use of 'void' Игорь Горлов
@ 2020-05-18 15:03 ` Niklas Gürtler
  2020-05-18 20:03   ` Jonathan Wakely
  0 siblings, 1 reply; 6+ messages in thread
From: Niklas Gürtler @ 2020-05-18 15:03 UTC (permalink / raw)
  To: gcc-help

On 5/18/20 12:30 PM, Игорь Горлов wrote:
> This program is not compatible with the C++17 standard. However, we can compile it with -std=gnu++17 (C++17 with GNU extensions), because one of that extensions permits calculations on void pointers.

It appears the extension is only for C, not for C++:
https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/Pointer-Arith.html#Pointer-Arith

Also, the C and C++ standards forbid subtracting pointers that do not
point into the same array, so subtracting the results of two distinct
'malloc' calls is undefined behaviour.

See e.g.
https://wiki.sei.cmu.edu/confluence/display/c/ARR36-C.+Do+not+subtract+or+compare+two+pointers+that+do+not+refer+to+the+same+array


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Invalid use of 'void'
  2020-05-18 15:03 ` Niklas Gürtler
@ 2020-05-18 20:03   ` Jonathan Wakely
  2020-05-19 11:07     ` Florian Weimer
  0 siblings, 1 reply; 6+ messages in thread
From: Jonathan Wakely @ 2020-05-18 20:03 UTC (permalink / raw)
  To: Игорь
	Горлов
  Cc: gcc-help, Niklas Gürtler

On Mon, 18 May 2020 at 16:15, Niklas Gürtler via Gcc-help
<gcc-help@gcc.gnu.org> wrote:
>
> On 5/18/20 12:30 PM, Игорь Горлов wrote:
> > This program is not compatible with the C++17 standard. However, we can compile it with -std=gnu++17 (C++17 with GNU extensions), because one of that extensions permits calculations on void pointers.

N.B. the behaviour you're seeing has nothing to do with C++17, you get
the same result for any version of C++.


> It appears the extension is only for C, not for C++:
> https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/Pointer-Arith.html#Pointer-Arith

Most C extensions are also valid in C++ mode, unless stated otherwise.
https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/C-Extensions.html

And G++ does allow arithmetic involving a void* and an integer, e.g.
p1 - 32 or p2 + 64, it doesn't allow subtracting one void* from the
other. So the extension is only partially supported for C++. We should
probably document that.

> Also, the C and C++ standards forbid subtracting pointers that do not
> point into the same array, so subtracting the results of two distinct
> 'malloc' calls is undefined behaviour.

Yes, you should really cast to uintptr_t first.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Invalid use of 'void'
  2020-05-18 20:03   ` Jonathan Wakely
@ 2020-05-19 11:07     ` Florian Weimer
  2020-05-19 11:31       ` Jonathan Wakely
  0 siblings, 1 reply; 6+ messages in thread
From: Florian Weimer @ 2020-05-19 11:07 UTC (permalink / raw)
  To: Jonathan Wakely via Gcc-help
  Cc: Игорь
	Горлов,
	Jonathan Wakely

* Jonathan Wakely via Gcc-help:

> And G++ does allow arithmetic involving a void* and an integer, e.g.
> p1 - 32 or p2 + 64, it doesn't allow subtracting one void* from the
> other. So the extension is only partially supported for C++. We should
> probably document that.

And it's a regression, GCC 2.7.2.3 can compile it, but GCC 2.95.2
cannot.  (Of course, I'm only half-serious here.)

The problem I see with such extensions in C++ is that they could alter
SFINAE outcomes.  But maybe that's less important these days because
people don't write custom type traits anymore.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Invalid use of 'void'
  2020-05-19 11:07     ` Florian Weimer
@ 2020-05-19 11:31       ` Jonathan Wakely
  0 siblings, 0 replies; 6+ messages in thread
From: Jonathan Wakely @ 2020-05-19 11:31 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Jonathan Wakely via Gcc-help,
	Игорь
	Горлов

On Tue, 19 May 2020 at 12:07, Florian Weimer <fweimer@redhat.com> wrote:
>
> * Jonathan Wakely via Gcc-help:
>
> > And G++ does allow arithmetic involving a void* and an integer, e.g.
> > p1 - 32 or p2 + 64, it doesn't allow subtracting one void* from the
> > other. So the extension is only partially supported for C++. We should
> > probably document that.
>
> And it's a regression, GCC 2.7.2.3 can compile it, but GCC 2.95.2
> cannot.  (Of course, I'm only half-serious here.)
>
> The problem I see with such extensions in C++ is that they could alter
> SFINAE outcomes.  But maybe that's less important these days because
> people don't write custom type traits anymore.

Most such extensions are disabled in SFINAE contexts:

template<typename T>
auto f(T* p) -> decltype(p+1) { return p + 1; }

int main()
{
  void* p = nullptr;
  p = p + 1;  // warning
  f(p); // error
}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Invalid use of 'void'
@ 2020-05-19 11:24 Игорь Горлов
  0 siblings, 0 replies; 6+ messages in thread
From: Игорь Горлов @ 2020-05-19 11:24 UTC (permalink / raw)
  To: gcc-help

Thank you for the valuable information, Niklas and Jonathan. I made my code to work by explicit conversions from void* to std::uintptr_t.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-05-19 11:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-18 10:30 Invalid use of 'void' Игорь Горлов
2020-05-18 15:03 ` Niklas Gürtler
2020-05-18 20:03   ` Jonathan Wakely
2020-05-19 11:07     ` Florian Weimer
2020-05-19 11:31       ` Jonathan Wakely
2020-05-19 11:24 Игорь Горлов

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).