0

I have a problem with a macro declared on another class to manage the traces.

I try to create another macro for the case when i'm using TEND ((void *) iRet) but it's not working neither ...

class trace.h:

#define TEND(val)  DTRACE(XZC_N0, "End - Returned value", val) \
          return(val);

class using macro but wrong!:

void *traitReponse( void *pv )
{

  INT       iRet = XZC_OK;

  iRet = inserBDTR(rsltDemande, pchDateRecherche, pchDateDeb, pchDateFin, pchLogin, pchISDN, pchEntite);


TEND ((void *) iRet)

}

Class using macro working fine without warning:

INT bdDisconnectDb ( )
{

    INT iRet = XZC_OK;

TBEGIN


if (0 != sqlca.sqlcode)
{

    iRet = XZC_NOK;
    goto FIN_FONCTION;
}
else
{
    TRACE(XZC_N2, "Disconnection successful")
}

FIN_FONCTION :
    TEND (iRet)

}

The compilation passed ok but i have these warnings:


In file included from tmp_ProcA.c:263:0:
tmp_ProcA.c: In function 'traitDemande':
tmp_ProcA.c:1514:8: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  TEND ((void *) (iRet))
        ^
xzenvir.h:255:12: note: in definition of macro 'TEND'
     return(val);
            ^

In file included from ProcA.c:263:0:
ProcA.c: In function 'traitDemande':
ProcA.c:1514:8: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  TEND ((void *) (iRet))
        ^
xzenvir.h:255:12: note: in definition of macro 'TEND'
     return(val);
            ^

In file included from bdconn.h:38:0,
                 from tmp_ProcB.c:263:
tmp_ProcB.c: In function 'traitReponse':
tmp_ProcB.c:1104:7: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
 TEND ((void *) (iRet))
       ^
xzenvir.h:255:12: note: in definition of macro 'TEND'
     return(val);
            ^

In file included from bdconn.h:38:0,
                 from ProcB.c:263:
ProcB.c: In function 'traitReponse':
ProcB.c:1104:7: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
 TEND ((void *) (iRet))
       ^
xzenvir.h:255:12: note: in definition of macro 'TEND'
     return(val);
            ^

I try to create another macro like this:

#define TEND_PROC((void *) val)  DTRACE(XZC_N0, "End - Returned value", val) \
          return(val);

but it's not working! can you please help me? Thanks in advance

Arepa
  • 25
  • 6
  • 3
    OT: your usage of `goto` is questionable. – Jabberwocky Aug 22 '19 at 10:03
  • `iRet` is an `INT` whose size is presumably 4. You cast it to `void*` which is a pointer, whose size is presumably 8, so what do you expect? – Jabberwocky Aug 22 '19 at 10:05
  • I use FIN_FONCTION on the traitReponse fonction too, so it's not the problem :/ – Arepa Aug 22 '19 at 10:06
  • 2
    Your `goto` is not actually wrong, it's usage is just questionable. It's an "Off Topic" comment showing that there is another problem in your code that is unrelated to your question. Read [this](https://stackoverflow.com/questions/3517726/what-is-wrong-with-using-goto) for more information – Jabberwocky Aug 22 '19 at 10:09
  • I should change to -> TEND ((INT *) iRET)? – Arepa Aug 22 '19 at 10:10
  • 2
    No!! `iRET` is also not `int *`, why is the return type of function is `void *` if it wants to return `INT`? – kiran Biradar Aug 22 '19 at 10:11
  • Ohh i see for the goto! it's a code that i recover to work it! so it will be part of work to avoid the goto, you r right! – Arepa Aug 22 '19 at 10:13
  • 1
    any reason to return `void` ptr from `traitReponse()` ? It seems that it should have `return` `int` instead – Nick S Aug 22 '19 at 10:14
  • 1
    @AnnyVivas concerning `goto`: if you're working with code written by someone else, it depends. You may leave it like that if the code runs correctly, it's up to you. – Jabberwocky Aug 22 '19 at 10:17
  • Yes i think the same than you! but at the same time i'm using a macro... not making a returning... if my macro applied a return as showing on the code `return(val)`, i should declare the fonction `traitReponse` as `int *traitReponse( void *pv )` to allow the macro return to be take account? – Arepa Aug 22 '19 at 10:19
  • 1
    If you have `INT iRet` (maybe because function `inserBDTR` returns this type) your function should return the same type `INT traitReponse(...)`. (Or the other way round using `void *iRet` and `void *traitReponse(...)` which would require `inserBDTR` to return a pointer as well.) – Bodo Aug 22 '19 at 10:21
  • @AnnyVivas probably, it's hard to tell without more context. – Jabberwocky Aug 22 '19 at 10:21
  • 1
    I do not see why the function would need to return `void*` – but if you ever *really* need to cast int to pointer, you should place an intermediate cast to integral of appropriate size, i. e. `(void*)(uintptr_t)val` – Aconcagua Aug 22 '19 at 10:51
  • 2
    Side note: Some consider placing extra parentheses around return values bad style (*'return is not a function'*). If you ever happen to write C++, then be aware that these parentheses can actually change semantics (e. g. preventing return value optimisation; in worst case they can even lead to invalid code: `decltype(auto) f() { int n; return (n); }` would return a (dangling!) reference to `n`). – Aconcagua Aug 22 '19 at 10:55
  • 1
    @Jabberwocky Yes it's a code that "works" normally so i prefer to keep the void. I try your suggestion for `(void*)(uintptr_t)val` and it works perfectly :D thank you so much!!! @Aconcagua :D – Arepa Aug 22 '19 at 12:29

1 Answers1

1

This warning ...

cast to pointer from integer of different size [-Wint-to-pointer-cast] and note: in definition of macro 'TEND'

... does not convey an inherent error in the function presented. It is allowed to perform such a conversion.

But there is a bad code smell to it, because there is no reason to expect that the resulting pointer value will be valid for accessing an object. The only things (reasonably) safe to do with it are store it, pass it around, and convert it back to an integer, and the former two are only safe where the context preserves the (lack of) significance of the value.

It is unclear why your particular compiler warns about one use of TEND() but not the other. It is conceivable that the macro INT is defined differently in those two contexts, but my guess would be that it has something to do with the fact that the second use also involves an implicit conversion of the pointer back to INT (and note also that allowing that without a cast is an extension to standard C if INT is in fact an integer type).

Furthermore, I observe that the issue being highlighted is context dependent. The sizes of C integer and pointer types vary among C implementations, and there was a time in the not too distant past when it was common for void * to be the same size as int. One would not expect a warning such as you ask about to be presented for your code by an implementation in which the integer size matches the pointer size. That does not mean that the code would correct for such an implementation, however. It might or might not be, regardless of whether a warning is emitted, just as it might still be ok in your particular usage, warning notwithstanding.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157