const question, take II

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Neels Hofmeyr nhofmeyr at sysmocom.de
Thu Mar 17 15:02:07 UTC 2016


On Thu, Mar 17, 2016 at 08:06:32AM +0100, Harald Welte wrote:
> This is standard practise, see the definition of memcpy:
> 
>  void *memcpy(void *dest, const void *src, size_t n);

I'm very familiar with that and want to use this everywhere and always,
which is why my conclusion that it apparently didn't work was quite a
disappointment. Glad to see that it does work after all...

What bugs me is that I don't understand the apparent corner case where it
doesn't work.

> > http://lists.osmocom.org/pipermail/openbsc/2016-January/001051.html
> > http://lists.osmocom.org/pipermail/openbsc/2016-January/001055.html
> > 
> > How is this different from the conclusion that Jacob confirmed two months
> > ago? Is it int (primitives) vs. struct??
> 
> from a quick look, the above discussion was about passing the address of
> a pointer, and of course if you pass that into a function, you expect
> the function to be able to modify the pointer stored at that address?

First, let's clarify:

const int * const x;
  the pointer x can't be modified, neither can the int at *x be modified.

const int *x;
  pointer x can be modified, but the int at *x can't be modified.

const int **x;
  x can be modified, *x can be modified, but the int at **x can't be modified.

right?

Let's look at a simple example that works without warning: I only want to
modify a pointer, not the ints.

  const int *func(const int *yy)
  {
          return yy + 1;
  }

  int main(void)
  {
          int y[2] = {23, 42};
          int *yy = y;
          return *func(yy); // returns 42
  }

This works perfectly. I pass a pointer to a mutable int, though the function
expects a pointer to a const int. No compiler warning.

And the failing example again; it does the exact same thing, only it returns
the modified pointer in an output-argument, using a pointer to a pointer to a
const int:

  void func(const int **yyy)
  {
          (*yyy) ++;
  }

  int main(void)
  {
          int y[2] = {23, 42};
          int *yy = y;
          func(&yy);

          return *yy; // returns 42
  }

And here I get the warning:

  cc     check.c   -o check
  check.c: In function ‘main’:
  check.c:11:14: warning: passing argument 1 of ‘func’ from incompatible pointer type
           func(yyy);
                ^
  check.c:1:6: note: expected ‘const int **’ but argument is of type ‘int **’
   void func(const int **yyy)
      ^

I'm quite happy that it seems to be only a corner case, and I'll be consting
aggressively and happily ever after :)

Yet it's a stupid corner case. Would be great if someone had an explanation to
this odd gcc behavior.

Maybe it's rather a question for another mailing list, too...

~Neels


-- 
- Neels Hofmeyr <nhofmeyr at sysmocom.de>          http://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschäftsführer / Managing Directors: Holger Freyther, Harald Welte
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.osmocom.org/pipermail/openbsc/attachments/20160317/9880b7b8/attachment.bin>


More information about the OpenBSC mailing list