sqlite 3.37.1: void function returns value

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

sqlite 3.37.1: void function returns value

jbulow
Just tried to update my sqlite version from 3.24 to 3.27.1 and the compiler
complained about a void function returning a value. I don't know about C,
but in C++ this is undefined behaviour and the clang compiler sometimes
generate an ud2 instruction for such code.

It's on line 58165 in (amalgamation) sqlite3.c.

/*
** Release a lock obtained by an earlier successful call to
** sqlite3PagerSnapshotCheck().
*/
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
  assert( pPager->pWal );
  return sqlite3WalSnapshotUnlock(pPager->pWal);
}
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

jbulow
The subject should say "3.27.1". Sorry!

On Mon, Feb 11, 2019 at 11:14 AM Jonas Bülow <[hidden email]> wrote:

> Just tried to update my sqlite version from 3.24 to 3.27.1 and the
> compiler complained about a void function returning a value. I don't know
> about C, but in C++ this is undefined behaviour and the clang compiler
> sometimes generate an ud2 instruction for such code.
>
> It's on line 58165 in (amalgamation) sqlite3.c.
>
> /*
> ** Release a lock obtained by an earlier successful call to
> ** sqlite3PagerSnapshotCheck().
> */
> SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
>   assert( pPager->pWal );
>   return sqlite3WalSnapshotUnlock(pPager->pWal);
> }
>
>
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

Dominique Devienne
On Mon, Feb 11, 2019 at 11:16 AM Jonas Bülow <[hidden email]> wrote:

> > Just tried to update my sqlite version from 3.24 to 3.27.1 and the
> > compiler complained about a void function returning a value. I don't know
> > about C, but in C++ this is undefined behaviour and the clang compiler
> > sometimes generate an ud2 instruction for such code.
>

Not if the expression of the return is itself void, i.e.
sqlite3WalSnapshotUnlock() is also a void function. (haven't checked).
See https://en.cppreference.com/w/cpp/language/return which is explicit
about it, and even shows it in an example. --DD
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

jbulow
Sorry, I missed some information. It is the MSVC v15.5 compiler that
complains:

sqlite3.c(58167): error C2220: warning treated as error - no 'object' file
generated [c:\work\sqlite-amalgamation-3270100\sqlite3.vcxproj]
sqlite3.c(58167): warning C4098: 'sqlite3PagerSnapshotUnlock': 'void'
function returning a value
[c:\work\sqlite-amalgamation-3270100\sqlite3.vcxproj]
Done Building Project "c:\sqlite-amalgamation-3270100\sqlite3.vcxproj"
(default targets) -- FAILED.


On Mon, Feb 11, 2019 at 11:21 AM Dominique Devienne <[hidden email]>
wrote:

> On Mon, Feb 11, 2019 at 11:16 AM Jonas Bülow <[hidden email]>
> wrote:
>
> > > Just tried to update my sqlite version from 3.24 to 3.27.1 and the
> > > compiler complained about a void function returning a value. I don't
> know
> > > about C, but in C++ this is undefined behaviour and the clang compiler
> > > sometimes generate an ud2 instruction for such code.
> >
>
> Not if the expression of the return is itself void, i.e.
> sqlite3WalSnapshotUnlock() is also a void function. (haven't checked).
> See https://en.cppreference.com/w/cpp/language/return which is explicit
> about it, and even shows it in an example. --DD
> _______________________________________________
> sqlite-users mailing list
> [hidden email]
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

Dominique Devienne
On Mon, Feb 11, 2019 at 11:31 AM Jonas Bülow <[hidden email]> wrote:

> Sorry, I missed some information. It is the MSVC v15.5 compiler that
> complains:
>
> sqlite3.c(58167): error C2220: warning treated as error - no 'object' file
> generated [c:\work\sqlite-amalgamation-3270100\sqlite3.vcxproj]
> sqlite3.c(58167): warning C4098: 'sqlite3PagerSnapshotUnlock': 'void'
> function returning a value
> [c:\work\sqlite-amalgamation-3270100\sqlite3.vcxproj]
> Done Building Project "c:\sqlite-amalgamation-3270100\sqlite3.vcxproj"
> (default targets) -- FAILED.
>

Buggy compiler? Using VS2017 (cl.exe 19.10) there are no warnings with the
CppReference code example.
But again, might depend on sqlite3WalSnapshotUnlock() being void or not.
--DD

PS: /Wall spews tons of warnings, in MS's own std lib headers...

d:\my\demo>cl /nologo /EHsc /W1 return-void.cpp
return-void.cpp

d:\my\demo>cl /nologo /EHsc /W2 return-void.cpp
return-void.cpp

d:\my\demo>cl /nologo /EHsc /W3 return-void.cpp
return-void.cpp

d:\my\demo>cl /nologo /EHsc /W4 return-void.cpp
return-void.cpp

d:\my\demo>type return-void.cpp
#include <iostream>
#include <string>
#include <utility>

void fa(int i)
{
    if (i == 2)
         return;
    std::cout << i << '\n';
} // implied return;

int fb(int i)
{
    if (i > 4)
         return 4;
    std::cout << i << '\n';
    return 2;
}

std::pair<std::string, int> fc(const char* p, int x)
{
    return {p, x};
}

void fd()
{
    return fa(10); // fa(10) is a void expression
}

int main()
{
    fa(2); // returns, does nothing when i==2
    fa(1); // prints its argument, then returns
    int i = fb(5); // returns 4
    i = fb(i); // prints its argument, returns 2
    std::cout << i << '\n'
              << fc("Hello", 7).second << '\n';
    fd();
}

d:\my\demo>return-void.exe
1
4
2
7
10

d:\my\demo>cl /EHsc /W4 return-void.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25019 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

return-void.cpp
Microsoft (R) Incremental Linker Version 14.10.25019.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:return-void.exe
return-void.obj

d:\my\demo>
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

jbulow
I'm using cl.exe v19.12.

To summarize:

SQLite 3.24 compiles fine with warning as error enabled with cl.exe v19.12
SQLite 3.27.1 does not compile with warning as error enabled with cl.exe
v19.12.

To me, it looks like a simple fix to avoid writing "return <expr>" in void
functions even if <expr> is a void function. It just looks broken and
obviously some compilers does not handle this correctly.

FWIW, cl.exe v19.12 does not complain about your example code
(return-coid.cpp)

If you convert your program to C:

#include <stdio.h>

void fa(int i)
{
  if (i == 2)
    return;
  printf("%d\n", i);
} // implied return;

int fb(int i)
{
  if (i > 4)
    return 4;
  printf("%d\n", i);
  return 2;
}

typedef struct {
  const char* p;
  int x;
} pair;

pair fc(const char* p, int x)
{
  pair r;
  r.p = p;
  r.x = x;
  return r;
}

void fd()
{
  return fa(10); // fa(10) is a void expression
}

int main()
{
  fa(2); // returns, does nothing when i==2
  fa(1); // prints its argument, then returns
  int i = fb(5); // returns 4
  i = fb(i); // prints its argument, returns 2

  printf("%d\n", i);

  printf("%d\n", fc("Hello", 7).x);
  fd();
}



The compiler complains:


Z:\retvoid>cl /EHsc /W4 return-void.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.12.25831 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

return-void.c
return-void.c(33): warning C4098: 'fd': 'void' function returning a value
Microsoft (R) Incremental Linker Version 14.12.25831.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:return-void.exe
return-void.obj


/Jonas


On Mon, Feb 11, 2019 at 11:58 AM Dominique Devienne <[hidden email]>
wrote:

> On Mon, Feb 11, 2019 at 11:31 AM Jonas Bülow <[hidden email]>
> wrote:
>
> > Sorry, I missed some information. It is the MSVC v15.5 compiler that
> > complains:
> >
> > sqlite3.c(58167): error C2220: warning treated as error - no 'object'
> file
> > generated [c:\work\sqlite-amalgamation-3270100\sqlite3.vcxproj]
> > sqlite3.c(58167): warning C4098: 'sqlite3PagerSnapshotUnlock': 'void'
> > function returning a value
> > [c:\work\sqlite-amalgamation-3270100\sqlite3.vcxproj]
> > Done Building Project "c:\sqlite-amalgamation-3270100\sqlite3.vcxproj"
> > (default targets) -- FAILED.
> >
>
> Buggy compiler? Using VS2017 (cl.exe 19.10) there are no warnings with the
> CppReference code example.
> But again, might depend on sqlite3WalSnapshotUnlock() being void or not.
> --DD
>
> PS: /Wall spews tons of warnings, in MS's own std lib headers...
>
> d:\my\demo>cl /nologo /EHsc /W1 return-void.cpp
> return-void.cpp
>
> d:\my\demo>cl /nologo /EHsc /W2 return-void.cpp
> return-void.cpp
>
> d:\my\demo>cl /nologo /EHsc /W3 return-void.cpp
> return-void.cpp
>
> d:\my\demo>cl /nologo /EHsc /W4 return-void.cpp
> return-void.cpp
>
> d:\my\demo>type return-void.cpp
> #include <iostream>
> #include <string>
> #include <utility>
>
> void fa(int i)
> {
>     if (i == 2)
>          return;
>     std::cout << i << '\n';
> } // implied return;
>
> int fb(int i)
> {
>     if (i > 4)
>          return 4;
>     std::cout << i << '\n';
>     return 2;
> }
>
> std::pair<std::string, int> fc(const char* p, int x)
> {
>     return {p, x};
> }
>
> void fd()
> {
>     return fa(10); // fa(10) is a void expression
> }
>
> int main()
> {
>     fa(2); // returns, does nothing when i==2
>     fa(1); // prints its argument, then returns
>     int i = fb(5); // returns 4
>     i = fb(i); // prints its argument, returns 2
>     std::cout << i << '\n'
>               << fc("Hello", 7).second << '\n';
>     fd();
> }
>
> d:\my\demo>return-void.exe
> 1
> 4
> 2
> 7
> 10
>
> d:\my\demo>cl /EHsc /W4 return-void.cpp
> Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25019 for x64
> Copyright (C) Microsoft Corporation.  All rights reserved.
>
> return-void.cpp
> Microsoft (R) Incremental Linker Version 14.10.25019.0
> Copyright (C) Microsoft Corporation.  All rights reserved.
>
> /out:return-void.exe
> return-void.obj
>
> d:\my\demo>
> _______________________________________________
> sqlite-users mailing list
> [hidden email]
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

Peter da Silva-2
I am pretty sure that the code is not legal C because it's using the return
value of a void function, as well as returning a value from a void
function. Compilers that "do what I mean" and accept it are in error. It's
certainly possible that some obscure clause in some C standard blesses it
but I can't imagine why they would.
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

Richard Damon
> On Feb 11, 2019, at 6:33 AM, Peter da Silva <[hidden email]> wrote:
>
> I am pretty sure that the code is not legal C because it's using the return
> value of a void function, as well as returning a value from a void
> function. Compilers that "do what I mean" and accept it are in error. It's
> certainly possible that some obscure clause in some C standard blesses it
> but I can't imagine why they would.

I would need to dig through the relevant Standards to confirm, but my memory was that C++ added this feature to help with templates (you might have a template where the return value was templates on type, so return <void expression> was a logical possibility). C did not need this, so didn’t adopt it (though possible some later version did for compatibility).

Many C Compilers are also C++.Compilers and often accept code that uses features of one language that aren’t in the other as an extension, generating a warning only if a ‘be fussy’ flag is set. (Few compilers are fully conforming to the Standard by default).

Even if this was adopted by C in some later Standard, the use of this syntax would be a needless requirement for a much later version of the Standard than would otherwise be needed.
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

Clemens Ladisch
In reply to this post by Peter da Silva-2
Peter da Silva wrote:
> I am pretty sure that the code is not legal C

Indeed; C99 and C11 say in 6.3.2.2:
| The (nonexistent) value of a void expression (an expression that has
| type void) shall not be used in any way [...]
and in 6.8.6.4:
| A return statement with an expression shall not appear in a function
| whose return type is void.

(And it has already been fixed two hours ago.)


Regards,
Clemens
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

Dominique Devienne
On Mon, Feb 11, 2019 at 1:11 PM Clemens Ladisch <[hidden email]> wrote:

> Peter da Silva wrote:
> > I am pretty sure that the code is not legal C
>
> Indeed; C99 and C11 say in 6.3.2.2:
> | The (nonexistent) value of a void expression (an expression that has
> | type void) shall not be used in any way [...]
> and in 6.8.6.4:
> | A return statement with an expression shall not appear in a function
> | whose return type is void.
>

Good to know. Thanks. I was merely pointing out that the OP's
"in C++ this is undefined behaviour" wasn't always true. --DD
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: sqlite 3.37.1: void function returns value

jbulow
Dominique, what I said was that it is undefined behaviour in C++ to return
a *value* in a void function. That is still true.

On Mon, Feb 11, 2019 at 2:49 PM Dominique Devienne <[hidden email]>
wrote:

> On Mon, Feb 11, 2019 at 1:11 PM Clemens Ladisch <[hidden email]>
> wrote:
>
> > Peter da Silva wrote:
> > > I am pretty sure that the code is not legal C
> >
> > Indeed; C99 and C11 say in 6.3.2.2:
> > | The (nonexistent) value of a void expression (an expression that has
> > | type void) shall not be used in any way [...]
> > and in 6.8.6.4:
> > | A return statement with an expression shall not appear in a function
> > | whose return type is void.
> >
>
> Good to know. Thanks. I was merely pointing out that the OP's
> "in C++ this is undefined behaviour" wasn't always true. --DD
> _______________________________________________
> sqlite-users mailing list
> [hidden email]
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users