FLTK logo

STR #3038

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 Home  |  Articles & FAQs  |  Bugs & Features  |  Documentation  |  Download  |  Screenshots  ]
 

Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]

STR #3038

Application:FLTK Library
Duplicate Of:STR #2813
Status:1 - Closed w/Resolution
Priority:2 - Low, e.g. a documentation error or undocumented side-effect
Scope:2 - Specific to an operating system
Subsystem:Core Library
Summary:cast to 'void *' from smaller integer type 'long'
Version:1.3-current
Created By:AnyCPU
Assigned To:AlbrechtS
Fix Version:1.3.4 (SVN: v10670)
Update Notification:

Receive EMails Don't Receive EMails

Trouble Report Files:

No files


Trouble Report Comments:


Name/Time/Date Text  
 
#1 AnyCPU
14:03 Jan 25, 2014
May cause problems on Win 64 bit systems with C++ type inferences.  
 
#2 AnyCPU
14:04 Jan 25, 2014
FL/Fl_Widget.H:836:58 ;)  
 
#3 greg.ercolano
09:22 Jan 27, 2014
Curious if this approach would work for us doing e.g. long -> void*, int -> void*, etc:

BEFORE:
    long val = 0x12345678;
    void *ptr;
    ptr = (void*)val1;   // WARNING (32bit val -> 64bit val)

AFTER:
    long val = 0x12345678;
    void *ptr;
    ptr = 0;                           // zeroes all 64bits of the ptr
    memcpy(&ptr, &val1, sizeof(val1)); // no warning, copies in lower 32bits

I figure as long as we use a similar technique going back out into
the destination data types, it should work..?

We could add a check to see if somehow sizeof(long) > sizeof(void*)
(which should be fatal, however unlikely that is), and throw a fatal()
error runtime error.

I don't think cstdint/stdint can help us here, as those include files
are not available on older C++ compilers we support (e.g. SGI), so I think we want to use 'old school' techniques here.

Or, another 'old school' possibility would be to use a union to convert the data types:

union Data {
   int integer_foo;
   void *pointer_foo;
}

This should work for conversion, avoids memcpy() byte-for-byte
copying, and we could still do the sizeof() check if needed.

To avoid runtime checks, perhaps instead we can add a check to
'configure' that checks if sizeof(void*) is smaller than sizeof(long)
and stop the build of FLTK if so. (might even be able to do this in the
VS IDE, not sure)

Michael responded to the above:
> #error macro can be used to stop compilation.
>
> To avoid runtime checks and for conversion a
> "union Data { ... }" is good (it's like COM's VARIANT).

Triggering the #error preprocessor would be good if there was
a way to test if sizeof(void*) < sizeof(long), but I'm not offhand
aware of a way the macro processor to such a test. If there is a way,
that'd be good because we could have a cross platform solution that
doesn't involve configure. (In VS builds, configure is not used)

We could use 'configure' to setup a macro variable that the macro preprocessor could test, but in that case we might as well have
configure throw the error.. and not sure what to do about VS,
might have to use some logic in the VS IDE project files or something.
 
 
#4 AnyCPU
15:41 Jan 27, 2014
configure or cmake, does not matter because for example via cmake I can do:

+        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+            SET(CLANG_WIN_NATIVE64 TRUE)
+        elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+            SET(CLANG_WIN_NATIVE32 TRUE)
+        endif(CMAKE_SIZEOF_VOID_P EQUAL 8)

If sizeof(void*) will equal to 8 then I can set that some macro defined.

in code:

#if defined(SOME_BAD_THING)
#error oh oh oh
#endif

Via configure I think it's possible generate include config header file with same macro SOME_BAD_THING.
 
 
#5 AnyCPU
15:44 Jan 27, 2014
http://www.cmake.org/cmake/help/git-master/module/CheckTypeSize.html

CMake's sizeof ;)
 
 
#6 greg.ercolano
11:59 Jan 28, 2014
OK, there's a running conversation in fltk.coredev right now..
    doesn't look good for any of the proposed solutions.

    I suggest following the conversation there, and when some kind
    of consensus is reached, we can reconvene in this STR to see
    what to do about it, if anything.
 
 
#7 dvega
18:00 Aug 26, 2014
I compiled fltk with MSYS and TDM-GCC 4.8.1.
To avoid these warnings I have made the following changes to the header files of fltk 1.3.2.

-----------------------
File: Fl_Widget.H


change the line 55:
typedef void (Fl_Callback1)(Fl_Widget*, long);

by:
#ifdef _WIN64
typedef void (Fl_Callback1)(Fl_Widget*, long long);
typedef void (Fl_Callback2)(Fl_Widget*, long);
#else
typedef void (Fl_Callback1)(Fl_Widget*, long);
#endif


change the line 575:
  void callback(Fl_Callback1*cb, long p=0) {callback_=(Fl_Callback*)cb; user_data_=(void*)p;}

by:
#ifdef _WIN64// I added the following typedef to avoid the long -> *void warning on WIN 64 (tested with TDM-GCC)
  void callback(Fl_Callback1*cb, long long p=0) {callback_=(Fl_Callback*)cb; user_data_=(void*)p;}
  void callback(Fl_Callback2*cb, long p=0) {callback_=(Fl_Callback*)cb; user_data_=(void*)(long long)p;}
#else
  void callback(Fl_Callback1*cb, long p=0) {callback_=(Fl_Callback*)cb; user_data_=(void*)p;}
#endif


change the line 591:
  long argument() const {return (long)(fl_intptr_t)user_data_;}

by:
#ifdef _WIN64
  long long argument() const {return (long long)(fl_intptr_t)user_data_;}
#else
  long argument() const {return (long)(fl_intptr_t)user_data_;}
#endif


change the line 597:
  void argument(long v) {user_data_ = (void*)v;}

by:
#ifdef _WIN64
  void argument(long long v) {user_data_ = (void*)v;}
#else
  void argument(long v) {user_data_ = (void*)v;}
#endif


change the line 835:
  void do_callback(Fl_Widget* o,long arg) {do_callback(o,(void*)arg);}

by:
#ifdef _WIN64
  void do_callback(Fl_Widget* o,long long arg) {do_callback(o,(void*)arg);}
#else
  void do_callback(Fl_Widget* o,long arg) {do_callback(o,(void*)arg);}
#endif

----------------------------------------------------------------------
File: forms.H

change the lines 221-222:
typedef void (*Forms_CB)(Fl_Widget*, long);
inline void fl_set_object_callback(Fl_Widget*o,Forms_CB c,long a) {o->callback(c,a);}

by:
#ifdef _WIN64
typedef void (*Forms_CB)(Fl_Widget*, long long);
inline void fl_set_object_callback(Fl_Widget*o,Forms_CB c,long long a) {o->callback(c,a);}
typedef void (*Forms_CB1)(Fl_Widget*, long);
inline void fl_set_object_callback(Fl_Widget*o,Forms_CB1 c,long a) {o->callback(c,a);}
#else
typedef void (*Forms_CB)(Fl_Widget*, long);
inline void fl_set_object_callback(Fl_Widget*o,Forms_CB c,long a) {o->callback(c,a);}
#endif


change the line 725:
inline void fl_set_menu_item_mode(Fl_Widget* o, int i, long x) {

by:
#ifdef _WIN64
inline void fl_set_menu_item_mode(Fl_Widget* o, int i, long long x) {
#else
inline void fl_set_menu_item_mode(Fl_Widget* o, int i, long x) {
#endif

----------------------------------------------------------------------
File: Fl_Menu_Item.H


change the line 243:
  void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;}

by:
#ifdef _WIN64
  void callback(Fl_Callback1*c, long long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;}
#else
  void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;}
#endif


change the line 259:
  long argument() const {return (long)(fl_intptr_t)user_data_;}

by:
#ifdef _WIN64
  long long argument() const {return (long long)(fl_intptr_t)user_data_;}
#else
  long argument() const {return (long)(fl_intptr_t)user_data_;}
#endif


change the line 267:
  void argument(long v) {user_data_ = (void*)v;}

by:
#ifdef _WIN64
  void argument(long long v) {user_data_ = (void*)v;}
#else
  void argument(long v) {user_data_ = (void*)v;}
#endif


change the line 391:
  void do_callback(Fl_Widget* o,long arg) const {callback_(o, (void*)arg);}

by:
#ifdef _WIN64
  void do_callback(Fl_Widget* o,long long arg) const {callback_(o, (void*)arg);}
#else
  void do_callback(Fl_Widget* o,long arg) const {callback_(o, (void*)arg);}
#endif

----------------------------------------------------------------------
File: glut.H


change the line 236:
#if defined(__LP64__)

by:
#if defined(__LP64__) || defined(_WIN64)
 
 
#8 ianmacarthur
03:55 Sep 05, 2014
See also;

#2878  #2813 #3038
 
 
#9 AlbrechtS
12:00 Jul 17, 2015
I believe that this STR is fixed since svn r 10670 (04 Apr 2015).
See also STR #2813, STR #2878 (both are closed).
http://www.fltk.org/str.php?L2813
http://www.fltk.org/str.php?L2878

Please confirm that the warnings are gone, or specify exactly the compiler and toolchain, setup (enabled warnings) etc..

Please do also post a log of the exact warnings.

Otherwise this STR will be closed in a few days.
 
 
#10 AlbrechtS
06:16 Jul 30, 2015
This STR has not been updated by the submitter for two or more weeks and has been closed as required by the FLTK Configuration Management Plan. If the issue still requires resolution, please re-submit a new STR.  
     

Return to Bugs & Features ]

 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.