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

Tkinter: incompatible pointer types warnings when built with Tcl 9 #112672

Closed
Tracked by #104568
chrstphrchvz opened this issue Dec 3, 2023 · 2 comments
Closed
Tracked by #104568
Assignees
Labels
3.12 bugs and security fixes 3.13 bugs and security fixes 3.14 new features, bugs and security fixes topic-tkinter

Comments

@chrstphrchvz
Copy link
Contributor

chrstphrchvz commented Dec 3, 2023

Tcl/Tk 9 changes C APIs to use a different type for sizes to allow transferring ≥32-bit sized things. The new type is Tcl_Size, which as of TIP 660 is defined as either ptrdiff_t in Tcl 9, or int in Tcl 8.7 for binary compatibility.

My impression is that Tcl/Tk wrappers such as Tkinter, which are primarily used for Tk GUI, have little if any need for this. But as of TIP 664, usage of APIs which previously expected int * must be updated for Tcl 9. There was previously effort in Tcl to continue allowing int * usage for compatibility, and maybe that would have been good enough for Tkinter, but others in the Tcl/Tk inner circle (who already wish to abandon Tcl/Tk < 9 entirely) rejected that approach. -Wincompatible-pointer-types warnings now seen under Tcl 9:

./Modules/_tkinter.c:504:21: warning: incompatible pointer types passing 'int *' to parameter of type 'Tcl_Size *' (aka 'long *') [-Wincompatible-pointer-types]
  504 |     const char *s = Tcl_GetStringFromObj(value, &len);
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tcl90/include/tclDecls.h:4235:36: note: expanded from macro 'Tcl_GetStringFromObj'
 4235 |                 (Tcl_GetStringFromObj)((objPtr), (sizePtr)))
      |                                                  ^~~~~~~~~
tcl90/include/tclDecls.h:1754:15: note: passing argument to parameter 'lengthPtr' here
 1754 |                                 Tcl_Size *lengthPtr);
      |                                           ^
./Modules/_tkinter.c:1138:29: warning: incompatible pointer types passing 'int *' to parameter of type 'Tcl_Size *' (aka 'long *') [-Wincompatible-pointer-types]
 1138 |         char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tcl90/include/tclDecls.h:4229:41: note: expanded from macro 'Tcl_GetByteArrayFromObj'
 4229 |                 (Tcl_GetBytesFromObj)(NULL, (objPtr), (sizePtr)))
      |                                                       ^~~~~~~~~
tcl90/include/tclDecls.h:1751:32: note: passing argument to parameter 'numBytesPtr' here
 1751 |                                 Tcl_Obj *objPtr, Tcl_Size *numBytesPtr);
      |                                                            ^
./Modules/_tkinter.c:1168:18: warning: incompatible pointer types passing 'int *' to parameter of type 'Tcl_Size *' (aka 'long *') [-Wincompatible-pointer-types]
 1168 |         status = Tcl_ListObjLength(interp, value, &size);
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tcl90/include/tclDecls.h:4244:44: note: expanded from macro 'Tcl_ListObjLength'
 4244 |                 (Tcl_ListObjLength)((interp), (listPtr), (lengthPtr)))
      |                                                          ^~~~~~~~~~~
tcl90/include/tclDecls.h:1790:33: note: passing argument to parameter 'lengthPtr' here
 1790 |                                 Tcl_Obj *listPtr, Tcl_Size *lengthPtr);
      |                                                             ^
./Modules/_tkinter.c:2104:13: warning: incompatible pointer types passing 'int *' to parameter of type 'Tcl_Size *' (aka 'long *') [-Wincompatible-pointer-types]
 2104 |         if (Tcl_ListObjGetElements(Tkapp_Interp(self),
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2105 |                                    ((PyTclObject*)arg)->value,
      |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2106 |                                    &objc, &objv) == TCL_ERROR) {
      |                                    ~~~~~~~~~~~~~
tcl90/include/tclDecls.h:4241:49: note: expanded from macro 'Tcl_ListObjGetElements'
 4241 |                 (Tcl_ListObjGetElements)((interp), (listPtr), (objcPtr), (objvPtr)))
      |                                                               ^~~~~~~~~
tcl90/include/tclDecls.h:1786:33: note: passing argument to parameter 'objcPtr' here
 1786 |                                 Tcl_Obj *listPtr, Tcl_Size *objcPtr,
      |                                                             ^
./Modules/_tkinter.c:2136:9: warning: incompatible pointer types passing 'int *' to parameter of type 'Tcl_Size *' (aka 'long *') [-Wincompatible-pointer-types]
 2136 |     if (Tcl_SplitList(Tkapp_Interp(self), list,
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2137 |                       &argc, &argv) == TCL_ERROR)  {
      |                       ~~~~~~~~~~~~~
tcl90/include/tclDecls.h:4250:40: note: expanded from macro 'Tcl_SplitList'
 4250 |                 (Tcl_SplitList)((interp), (listStr), (argcPtr), (argvPtr)))
      |                                                      ^~~~~~~~~
tcl90/include/tclDecls.h:1796:36: note: passing argument to parameter 'argcPtr' here
 1796 |                                 const char *listStr, Tcl_Size *argcPtr,
      |                                                                ^
5 warnings generated.

Code intending to remain compatible with Tcl 8.6 is suggested to use the following after including tcl.h:

#ifndef TCL_SIZE_MAX
typedef int Tcl_Size;
# define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj
# define Tcl_NewSizeIntObj Tcl_NewIntObj
# define TCL_SIZE_MAX      INT_MAX
# define TCL_SIZE_MODIFIER ""
#endif

I intend to open a PR updating _tkinter.c to pass Tcl_Size * where needed.

There are several other instances where Tkinter assumes Tcl expectsint or something not larger than INT_MAX, but migrating those to Tcl_Size and TCL_SIZE_MAX seems optional.

Linked PRs

@chrstphrchvz
Copy link
Contributor Author

Code intending to remain compatible with Tcl 8.6 is suggested to use the following after including tcl.h:

#ifndef TCL_SIZE_MAX
typedef int Tcl_Size;
# define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj
# define Tcl_NewSizeIntObj Tcl_NewIntObj
# define TCL_SIZE_MAX      INT_MAX
# define TCL_SIZE_MODIFIER ""
#endif

There is ongoing debate upstream about what is actually needed here, most recently in https://sourceforge.net/p/tcl/mailman/tcl-core/thread/74564788-7d69-4c42-9205-c5f3e6a1409d%40elmicron.de/
Some want Tcl_Size to be a macro and not a typedef. Some do not want to force downstream projects/users to need “boilerplate” for 8.6 compatibility. Others do not care about Tcl/Tk < 9.0 and will gladly pass the buck downstream.

@serhiy-storchaka serhiy-storchaka self-assigned this Jun 4, 2024
serhiy-storchaka added a commit that referenced this issue Jun 4, 2024
* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@serhiy-storchaka
Copy link
Member

In future we may change more code to support longer data in Python->Tcl conversion. But this requires testing, because not always the library supports larger than 2GiB data even if the size type is 64-bit (for example SQLite has 32-bit limitation even in its 64-bit API),

barneygale pushed a commit to barneygale/cpython that referenced this issue Jun 5, 2024
* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@serhiy-storchaka serhiy-storchaka added needs backport to 3.13 bugs and security fixes 3.13 bugs and security fixes 3.14 new features, bugs and security fixes and removed needs backport to 3.13 bugs and security fixes labels Jun 7, 2024
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jun 7, 2024
* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

(cherry picked from commit e079935)

Co-authored-by: Christopher Chavez <chrischavez@gmx.us>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@serhiy-storchaka serhiy-storchaka added the 3.12 bugs and security fixes label Jun 7, 2024
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jun 7, 2024
* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

(cherry picked from commit e079935)

Co-authored-by: Christopher Chavez <chrischavez@gmx.us>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this issue Jun 7, 2024
…0208)

* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

(cherry picked from commit e079935)

Co-authored-by: Christopher Chavez <chrischavez@gmx.us>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this issue Jun 7, 2024
…0209)

* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

(cherry picked from commit e079935)

Co-authored-by: Christopher Chavez <chrischavez@gmx.us>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
noahbkim pushed a commit to hudson-trading/cpython that referenced this issue Jul 11, 2024
* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
* Add declaration of Tcl_AppInit(), missing in Tcl 9.0.
* Use Tcl_Size instead of int where needed.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 bugs and security fixes 3.13 bugs and security fixes 3.14 new features, bugs and security fixes topic-tkinter
Projects
None yet
Development

No branches or pull requests

3 participants