Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alloc.h contains "static" C-functions #7461

Closed
vicuna opened this issue Jan 13, 2017 · 8 comments
Closed

alloc.h contains "static" C-functions #7461

vicuna opened this issue Jan 13, 2017 · 8 comments
Assignees

Comments

@vicuna
Copy link

vicuna commented Jan 13, 2017

Original bug ID: 7461
Reporter: @mmottl
Assigned to: @dra27
Status: closed (set by @dra27 on 2017-01-15T14:54:23Z)
Resolution: not a bug
Priority: normal
Severity: minor
Version: 4.04.0
Category: runtime system and C interface
Monitored by: @mmottl

Bug description

C-compilers may warn about unused functions due to the declaration of "static" functions in the header file "alloc.h". E.g.:


In file included from src/utils_c.c:28:
/Users/mmottl/.opam/4.04.0/lib/ocaml/caml/alloc.h:59:21: warning: unused function 'caml_alloc_unboxed' [-Wunused-function]
static inline value caml_alloc_unboxed (value arg) { return arg; }
^
/Users/mmottl/.opam/4.04.0/lib/ocaml/caml/alloc.h:60:21: warning: unused function 'caml_alloc_boxed' [-Wunused-function]
static inline value caml_alloc_boxed (value arg) {
^
/Users/mmottl/.opam/4.04.0/lib/ocaml/caml/alloc.h:65:21: warning: unused function 'caml_field_unboxed' [-Wunused-function]
static inline value caml_field_unboxed (value arg) { return arg; }
^
/Users/mmottl/.opam/4.04.0/lib/ocaml/caml/alloc.h:66:21: warning: unused function 'caml_field_boxed' [-Wunused-function]
static inline value caml_field_boxed (value arg) { return Field (arg, 0); }

It is generally inadvisable to declare functions as static in header files. A good explanation of the problem can be found in this answer to a Stackoverflow question:

http://stackoverflow.com/a/2846143/2065753

I assume the intention was to support inlining of these functions for efficiency reasons. Maybe LTO (Link Time Optimization), which is supported by GCC, is a cleaner solution. See e.g.: http://stackoverflow.com/a/5988418/2065753

If you decide to keep these functions static in the header file, you may want to add "attribute((unused))" to suppress warnings in user code.

@vicuna
Copy link
Author

vicuna commented Jan 14, 2017

Comment author: @dra27

Note for Windows that the equivalent MSVC options are /GL for the compiler and /LTCG for the linker. However, at least up to Visual Studio 2015 (CL 19) the compiler doesn't appear to warn about unused static functions at any level.

I am struggling to reproduce this with GCC, though - for my experiments the inline attribute suppresses the warning. Which version of GCC are you using?

@vicuna
Copy link
Author

vicuna commented Jan 14, 2017

Comment author: @xavierleroy

"static inline" functions in header files are a superior replacement to macro definitions. I would certainly not trust LTO of non-inline functions to achieve the same performance and achieve it consistently.

As @dra wrote, the question is to understand which compilers unhelpfully warn about this idiom and to deal with them.

@vicuna
Copy link
Author

vicuna commented Jan 14, 2017

Comment author: @mmottl

I should have mentioned that GCC was called with "-Wunused", which is surely a frequently passed and useful flag. I don't know about the maturity of LTO so if you prefer "static inline" functions in headers for these admittedly performance-critical functions, adding compiler attributes or pragmas for warning suppression may be the best choice.

The "memory.h" header already defines macros (e.g. CAMLunused_start) for declaring potentially unused code in a somewhat portable way. Maybe these macros should be factored out into a separate file and shared among header files that use the "static inline" performance hack. Affected header files in "caml" would be: "alloc.h", "minor_gc.h", and "weak.h".

@vicuna
Copy link
Author

vicuna commented Jan 14, 2017

Comment author: @dra27

With GCC 6.2.0 on amd64, I still don't see that warning emitted (with -Wunused or -Wall) unless the inline attribute is removed, though?

We shouldn't just lift CAMLunused_start from memory.h - it suppresses the wrong warning for MSVC in this context (academic, but I don't like the idea of headers suppressing a warning which won't happen)

@vicuna
Copy link
Author

vicuna commented Jan 14, 2017

Comment author: @dra27

Further, this related bug suggests that if GCC is giving Wunused-function then there's a bug in your GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55830

@vicuna
Copy link
Author

vicuna commented Jan 14, 2017

Comment author: @mmottl

I've tested this now with different compilers: clang on Mac OS X Sierra and gcc 5.4 as well as gcc 6.3 from MacPorts. They all give me the same warning. The warning is actually not generated by the -Wunused flag but already by -Wall. Here is an example invocation:

gcc-mp-6 -Wall -c -I'/Users/mmottl/.opam/4.04.0/lib/ocaml' 'src/utils_c.c'

@vicuna
Copy link
Author

vicuna commented Jan 15, 2017

Comment author: @dra27

OK, I've tried GCC 6.3.0 on Ubuntu 17.04 (14 Jan 2017) and I'm still not getting it, I'm afraid! In the root of a configured ocaml git clone, I've created:

#include <caml/memory.h>
#include <caml/alloc.h>

static void warn_about_me(void) {
return;
}

static inline void dont_warn_about_me(void) {
return;
}

CAMLprim value MyPrimitive(value unit) {
CAMLparam1(unit);

CAMLreturn(unit);
}

which I'm then compiling with:

gcc -c -Wall -I byterun foo.c

and I only see -Wunused-function for the function warn_about_me. If I edit byterun/caml/alloc.h and remove any of the inline's then I see it for those functions too.

Incidentally, this really doesn't seem to be a hack - the GCC manual itself refers to it as a superior technique to macros for inlining in headers.

Is there anything in what you're doing which may be disabling (or #define'ing) away the inline keyword? Is it possible to try your code?

@vicuna
Copy link
Author

vicuna commented Jan 15, 2017

Comment author: @mmottl

Indeed, I should have followed other include files to see that the inline keyword had been modified via macros depending on the compiler and STDC version. This was really old code that may not be relevant anymore. I hope getting rid of it doesn't cause portability issues. The warning is gone now and the issue can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants