Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #136740 > unrolled thread

Unwanted, implicit type conversion to a pointer when a value is zero?

Started byjladasky@itu.edu
First post2018-10-12 17:12 -0700
Last post2018-10-13 12:57 -0700
Articles 7 — 4 participants

Back to article view | Back to comp.lang.c


Contents

  Unwanted, implicit type conversion to a pointer when a value is zero? jladasky@itu.edu - 2018-10-12 17:12 -0700
    Re: Unwanted, implicit type conversion to a pointer when a value is zero? David Brown <david.brown@hesbynett.no> - 2018-10-13 12:54 +0200
      Re: Unwanted, implicit type conversion to a pointer when a value is zero? Keith Thompson <kst-u@mib.org> - 2018-10-13 11:36 -0700
    Re: Unwanted, implicit type conversion to a pointer when a value is zero? Bart <bc@freeuk.com> - 2018-10-13 15:19 +0100
      Re: Unwanted, implicit type conversion to a pointer when a value is zero? Keith Thompson <kst-u@mib.org> - 2018-10-13 11:37 -0700
        Re: Unwanted, implicit type conversion to a pointer when a value is zero? Bart <bc@freeuk.com> - 2018-10-13 20:21 +0100
          Re: Unwanted, implicit type conversion to a pointer when a value is zero? Keith Thompson <kst-u@mib.org> - 2018-10-13 12:57 -0700

#136740 — Unwanted, implicit type conversion to a pointer when a value is zero?

Fromjladasky@itu.edu
Date2018-10-12 17:12 -0700
SubjectUnwanted, implicit type conversion to a pointer when a value is zero?
Message-ID<eaf12c90-58a9-4a8f-b12f-4c0f79a50c59@googlegroups.com>
I just encountered a surprising situation.  I hope that I do not omit too much detail in describing it, but I'm trying to avoid spending a lot of time on the embedded system library I'm using, as I believe this is a C language issue and not an issue with the library.

I have a program with two very similar lines:

    nrf_drv_twi_tx(&m_twi_master, MAX20303_MAIN_I2C_ADDR, 0x00, 1, true);

and

    nrf_drv_twi_tx(&m_twi_master, MAX20303_MAIN_I2C_ADDR, 0x01, 1, true);

The only difference is the third argument, as you can see.

I'm compiling with GCC, using very strict error checking.  All warnings are promoted to errors.  The first line compiles successfully.  The second line fails thus:

    ./main.c:59:59: error: passing argument 3 of 'nrf_drv_twi_tx' makes
    pointer from integer without a cast [-Werror=int-conversion]
     nrf_drv_twi_tx(&m_twi_master, MAX20303_MAIN_I2C_ADDR, 0x01, 1, true);
                                                           ^~~~
    In file included from ./twi.h:12:0,
                     from ./main.c:18:
    /home/.../nrf_drv_twi.h:303:12: note: expected 'const uint8_t * {aka
    const unsigned char *}' but argument is of type 'int'
    ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance,
               ^~~~~~~~~~~~~~

Now, I know that I've made an error in each case, I need to supply a pointer to a data buffer for that third argument rather than (in my cases a single byte of) the data that I want to send.  However, I am surprised that the first function call does not generate an error if that is true.  GCC was happy to cast 0x00 to a pointer (probably to NULL?).  It only complained when I tried to cast 0x01 to a pointer.  Is this expected?  Desirable?

Thanks for your insights.

[toc] | [next] | [standalone]


#136744

FromDavid Brown <david.brown@hesbynett.no>
Date2018-10-13 12:54 +0200
Message-ID<ppsisu$e0k$1@dont-email.me>
In reply to#136740
On 13/10/18 02:12, jladasky@itu.edu wrote:
> I just encountered a surprising situation.  I hope that I do not omit too much detail in describing it, but I'm trying to avoid spending a lot of time on the embedded system library I'm using, as I believe this is a C language issue and not an issue with the library.
> 
> I have a program with two very similar lines:
> 
>      nrf_drv_twi_tx(&m_twi_master, MAX20303_MAIN_I2C_ADDR, 0x00, 1, true);
> 
> and
> 
>      nrf_drv_twi_tx(&m_twi_master, MAX20303_MAIN_I2C_ADDR, 0x01, 1, true);
> 
> The only difference is the third argument, as you can see.
> 
> I'm compiling with GCC, using very strict error checking.  All warnings are promoted to errors.  The first line compiles successfully.  The second line fails thus:
> 
>      ./main.c:59:59: error: passing argument 3 of 'nrf_drv_twi_tx' makes
>      pointer from integer without a cast [-Werror=int-conversion]
>       nrf_drv_twi_tx(&m_twi_master, MAX20303_MAIN_I2C_ADDR, 0x01, 1, true);
>                                                             ^~~~
>      In file included from ./twi.h:12:0,
>                       from ./main.c:18:
>      /home/.../nrf_drv_twi.h:303:12: note: expected 'const uint8_t * {aka
>      const unsigned char *}' but argument is of type 'int'
>      ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance,
>                 ^~~~~~~~~~~~~~
> 
> Now, I know that I've made an error in each case, I need to supply a pointer to a data buffer for that third argument rather than (in my cases a single byte of) the data that I want to send.  However, I am surprised that the first function call does not generate an error if that is true.  GCC was happy to cast 0x00 to a pointer (probably to NULL?).  It only complained when I tried to cast 0x01 to a pointer.  Is this expected?  Desirable?
> 
> Thanks for your insights.
> 


Yes.  The integer constant 0 is a "null pointer" in C.  (Note that this 
is /not/ the same as an int variable that happens to be 0!)  It is 
usable as a pointer of any time, usually to indicate an invalid pointer 
value.

This is far too deeply ingrained in C for there to be a warning about 
passing 0 when a pointer is called for, as it is valid and very commonly 
used.

In modern C++, "nullptr" should be used instead of 0 for null pointers, 
and gcc has a warning "-Wzero-as-null-pointer-constant".  But that is 
not available for C compilation.



[toc] | [prev] | [next] | [standalone]


#136751

FromKeith Thompson <kst-u@mib.org>
Date2018-10-13 11:36 -0700
Message-ID<ln36t9wv5w.fsf@kst-u.example.com>
In reply to#136744
David Brown <david.brown@hesbynett.no> writes:
[...]
> Yes.  The integer constant 0 is a "null pointer" in C.  (Note that this 
> is /not/ the same as an int variable that happens to be 0!)  It is 
> usable as a pointer of any time, usually to indicate an invalid pointer 
> value.

The integer constant 0 is a *null pointer constant*, not a *null
pointer*.

A null pointer constant is a syntactic entity that exists in source
code.  A null pointer is a value that exists as a program is running.

A null pointer constant may be implicitly converted to a pointer
type, but the constant 0 is still of type int.

(I think somebody else already posted the standard's definition of
"null pointer constant".)

Note that this implicit conversion does not happen in all cases.
For example, this:
    printf("%p\n", 0);
does not convert the 0 to void*, and therefore has undefined behavior.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#136750

FromBart <bc@freeuk.com>
Date2018-10-13 15:19 +0100
Message-ID<G9nwD.18529$I34.17228@fx43.am4>
In reply to#136740
On 13/10/2018 01:12, jladasky@itu.edu wrote:

> Now, I know that I've made an error in each case, I need to supply a pointer to a data buffer for that third argument rather than (in my cases a single byte of) the data that I want to send.  However, I am surprised that the first function call does not generate an error if that is true.  GCC was happy to cast 0x00 to a pointer (probably to NULL?).  It only complained when I tried to cast 0x01 to a pointer.  Is this expected?  Desirable?


The value of 0 is very commonly used to indicate a pointer that doesn't 
point to anything (or, for example, that this particular call is not 
supplying that argument so it should not be used).

But what would a value of 1 mean in your program?

It is most likely an error. That's why you need to explicitly cast a 
constant integer to a pointer, it is not zero (and all variable 
integers). To show here that passing 1 for a pointer is intentional.


-- 
bart

[toc] | [prev] | [next] | [standalone]


#136752

FromKeith Thompson <kst-u@mib.org>
Date2018-10-13 11:37 -0700
Message-ID<lny3b1vgjz.fsf@kst-u.example.com>
In reply to#136750
Bart <bc@freeuk.com> writes:
> On 13/10/2018 01:12, jladasky@itu.edu wrote:
>> Now, I know that I've made an error in each case, I need to supply a
>> pointer to a data buffer for that third argument rather than (in my
>> cases a single byte of) the data that I want to send.  However, I am
>> surprised that the first function call does not generate an error if
>> that is true.  GCC was happy to cast 0x00 to a pointer (probably to
>> NULL?).  It only complained when I tried to cast 0x01 to a pointer.
>> Is this expected?  Desirable?
>
>
> The value of 0 is very commonly used to indicate a pointer that doesn't 
> point to anything (or, for example, that this particular call is not 
> supplying that argument so it should not be used).
>
> But what would a value of 1 mean in your program?
>
> It is most likely an error. That's why you need to explicitly cast a 
> constant integer to a pointer, it is not zero (and all variable 
> integers). To show here that passing 1 for a pointer is intentional.

The OP already said that he knows it's an error.  He's asking why the
error was diagnosed for 0x01 but not for 0x00 (and that's been
answered).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#136753

FromBart <bc@freeuk.com>
Date2018-10-13 20:21 +0100
Message-ID<9BrwD.83978$522.7751@fx35.am4>
In reply to#136752
On 13/10/2018 19:37, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:
>> On 13/10/2018 01:12, jladasky@itu.edu wrote:
>>> Now, I know that I've made an error in each case, I need to supply a
>>> pointer to a data buffer for that third argument rather than (in my
>>> cases a single byte of) the data that I want to send.  However, I am
>>> surprised that the first function call does not generate an error if
>>> that is true.  GCC was happy to cast 0x00 to a pointer (probably to
>>> NULL?).  It only complained when I tried to cast 0x01 to a pointer.
>>> Is this expected?  Desirable?
>>
>>
>> The value of 0 is very commonly used to indicate a pointer that doesn't
>> point to anything (or, for example, that this particular call is not
>> supplying that argument so it should not be used).
>>
>> But what would a value of 1 mean in your program?
>>
>> It is most likely an error. That's why you need to explicitly cast a
>> constant integer to a pointer, it is not zero (and all variable
>> integers). To show here that passing 1 for a pointer is intentional.
> 
> The OP already said that he knows it's an error.

Which one, the 00, or the 01? They said they thought both were errors.

   He's asking why the
> error was diagnosed for 0x01 but not for 0x00 (and that's been
> answered).

Who by, apart from me? I don't think anyone said anything about the 01 
value.

[toc] | [prev] | [next] | [standalone]


#136755

FromKeith Thompson <kst-u@mib.org>
Date2018-10-13 12:57 -0700
Message-ID<lntvlpvcuh.fsf@kst-u.example.com>
In reply to#136753
Bart <bc@freeuk.com> writes:
> On 13/10/2018 19:37, Keith Thompson wrote:
[...]
>> The OP already said that he knows it's an error.
>
> Which one, the 00, or the 01? They said they thought both were errors.

Yes.  Both are logical errors.  Only the 0x01 was diagnosed by the
compiler.

>    He's asking why the
>> error was diagnosed for 0x01 but not for 0x00 (and that's been
>> answered).
>
> Who by, apart from me? I don't think anyone said anything about the 01 
> value.

The 0x01 error was diagnosed by the compiler, because 0x01 cannot be
implicitly converted to a pointer type.  The OP showed us the error
message.  Several others have explained why the 0x00 logical error was
not diagnosed (because it's a null pointer constant).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web