Skip to content

Conversation

@pedro-w
Copy link
Contributor

@pedro-w pedro-w commented Sep 11, 2025

Description

The message toBase treats its receiver, a sequence, as a number formatted as a string, and returns a number formatted as a string in a different base.

On windows MSVC it is not able to deal with a number greater than 0xFFFFFFFF because unsigned long on that platform is 32-bit. This causes a problem for uniqueHexId because the unique id is a pointer-sized (i.e. 64-bit) quantity. Other messages which rely on uniqueHexId, such as asSimpleString are affected.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring

Related Issues

Fixes #480

Changes Made

The current code parses a string to a number, then converts that number to a string.

  • Use strtoull instead of strtoul on Windows only.
  • Use an explicitly sized type, namely uint64_t, for intermediate values

Also, remove a code comment says "Only base 8 and 16 are currently supported" because this is untrue.

Testing

  • All existing tests pass
  • Added new tests for the changes
  • Tested on the following platforms:
    • Linux
    • macOS (Intel)
    • macOS (Apple Silicon)
    • Windows
    • Other:

Test Commands

Before:

Io> Object asSimpleString
==> Object_0xffffffff

After:

Io> Object asSimpleString
==> Object_0x146297d81c0

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

@stevedekorte
Copy link
Member

Thanks for the pull request. Could you modify it to work on 32bit as well?

@pedro-w
Copy link
Contributor Author

pedro-w commented Sep 13, 2025

Sure, do you mean specifically 32-bit windows or other platforms as well?

[edit] I cross-compiled for Windows x86 using MSVC, it works still because, even though the intermediate value is 64 bit, its upper bits are all zero so what gets printed is a 'short' hex number

Microsoft (R) COFF/PE Dumper Version 14.44.35216.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file _x86build\_build\binaries\Debug\io.exe

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES
             14C machine (x86)
               7 number of sections
        68C53996 time date stamp Sat Sep 13 10:29:58 2025
Io 20170906
Io> Object asSimpleString
==> Object_0x8d0a58

@stevedekorte
Copy link
Member

Sure, do you mean specifically 32-bit windows or other platforms as well?

Other 32bit platforms. I'm also not entirely opposed to making Io 64bit (or greater) only if there is a good reason to do so, but if we go that route, we should make it clear in the docs and throw a clear error when attempting to compile for smaller word size hardware.

@pedro-w
Copy link
Contributor Author

pedro-w commented Sep 15, 2025

I see what you mean. I can try to find an older Linux or BSD and run it under an emulator. As I mentioned above, the Windows version was OK (32-bit app running on 64-bit Windows). I don't think the changes I made will stop it working, as 32-bit systems can do 64-bit arithmetic albeit with some overhead compared to native.

I read an article just last week on LWN. It said that the main issue was disappearing hardware; it is basically only embedded systems left now. For io another problem might be finding a version of cmake that would work.

Overall I agree there's no point removing 32-bit support just for the sake of it.

@stevedekorte
Copy link
Member

I think it's fine to just write it in a way that should work on 32bit without testing it. I'd guess Claude would be able to easily do this.

@pedro-w
Copy link
Contributor Author

pedro-w commented Sep 16, 2025

I tested on an old Raspberry Pi which is ARMv7. It worked (I'm only doing very superficial testing, mind). I am going to slightly change this PR to use uintptr_t instead of uint64_t, so it will be the same size as a pointer on both 32- and 64- bit, which is what is needed.

I don't know why Windows used strtoul and everything else uses asDouble (which is implemented by strtod) but I'm assuming there was a good reason for it; best to keep changes to a minimum I think.

(sorry this is becoming a bit of a long thread for a 2 line patch!)

@stevedekorte
Copy link
Member

Sounds good. Please let me know when it's ready.

Because on Windows MSVC, unsigned long is 32-bit and on other
platforms it is 64-bit, so better to use a type with an
explicit size.
@pedro-w
Copy link
Contributor Author

pedro-w commented Sep 17, 2025

I've updated and force-pushed it, should be OK now.

@stevedekorte stevedekorte merged commit 8db0702 into IoLanguage:master Sep 17, 2025
3 of 8 checks passed
@stevedekorte
Copy link
Member

Looks good - thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Object asSimpleString is not very useful on Windows

2 participants