-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Pointer's copy_from|copy_to|move_from|move_to are inherently broken. #4589
Comments
EDIT: lol I just randomly found this 5 years later; younger me was being extremely stupid here. |
Actually, no; it'd have to be four gigabytes of data in one copy in order to cause trouble. |
If you think, real programs doesn't do such "crazy" things, you are not right. |
Crystal isn't C. Please keep this in mind and be nice when asking questions or reporting issues. All sizes in Crystal (e.g. String, Array, StaticArray, Slice or Pointer) are clamped at Now, since we clamp values, and users may try inconsiderate sizes, we should have bound checks and raise an ArgumentError when values are too large. Would you be willing to open a pull request, with passing specs? Relates to #3209. |
@ysbaddaden I think that |
Reading @RX14 that would defeat the purpose: if I can allocate a Slice with Int64 size, while should String or Array be limited? |
@RX14, @ysbaddaden unfortunately mentioned lines are from pointer.cr , so it is Pointer broken.
I'm not against using Int32 as base type for size of all standard-library containers. That is really ok.
Sizes, but not memory size of allocated pointer. How much will consume |
@ysbaddaden because array uses realloc while slice doesn't. Array owns the memory it allocates and uses realloc assuming the memory is small. String because 2gb strings you've gone too far. Whereas slice represents a pointer and a size. A window on memory. It makes no assumptions about what's in that memory it just let's you access it. That memory could come from a C program which allocates more than 2gb of memory. A slice could be used to represent a mmap of a file on disk. These are perfectly valid usecases for a slice larger than 2gb. |
@RX14 This is a valid claim, but Crystal doesn't aim for this, and we shouldn't care about potential large allocations C. If we assume Int32 is plaintly enough, then Slice must follow. Developers are discouraged to use We're already kinda forced to have |
Either you should raise, or just fix move_from, copy_from and clear. Lets be clear:
|
Reading very large files is a common task even for applications with 32-bit addressing. These are tools such as grep, diff, databases, video processing and much more. In this case, the Flle MMAP is fine and yes, it requires 64-bit addressing in files and memory. |
Disappointed with these decisions. "Crystal is not C" isn't a valid excuse for not making a low level feature work properly. |
Just note that it's short fix for crystal-lang#4589 only.
I hope that these are just leftovers from the past. There certainly has been an effort to clean up these "32isms". Also note that And yeah, some comments here have been worrying. It's never OK to have randomly breaking code when someone happens to allocate a memory region over 2GB. |
Just note that it's short fix for crystal-lang#4589 only.
Just note that it's short fix for crystal-lang#4589 only.
…g two pointers. ptrdiff_t is used for pointer arithmetic and array indexing, if negative values are possible. Refs crystal-lang#823, crystal-lang#4589.
…g two pointers. ptrdiff_t is used for pointer arithmetic and array indexing, if negative values are possible. Refs crystal-lang#823, crystal-lang#4589.
All of this should be fixed, but it's hard. The main issue is that if Those As @oprypin says, most of these things are left-over from the past. We should fix them slowly, though I don't know what maximum sizes should Slice, String, Array, Hash, etc. have. Maybe |
There's an easy fix for this, it's making a new numeric class like PointerAddress that uses 32 or 64 bit ints under the hood. |
@zatherz As we pointed - there is LibC::SizeT and we need simply LibC::PtrDiffT too. But it need some time to rework things inside the compiler (#4624 (review)) |
So, what's the real issue here? What code breaks? I think we can:
Is there any other thing that needs a fix? |
|
We can probably limit the size of an array. Why do you want an array that big? What's a use case for that? |
@asterite you asked wrong question. What will change if it will be not 2G elements is annoying, but acceptable limit. If there will be stricter limit, Crystal will loose a lot of usability. And, any way, |
Java's So I guess Java is a toy? |
I understand now. We can have Int32::MAX elements, but it still behaves wrong. The problem is that I can't seem to understand the issue from those one-liners. Would you care to explain what's wrong with Array implementation that makes it work wrong, and why my comments here ( #4589 (comment) ) wouldn't fix that issue? |
I think, problem is on Pointer side.
I think, it will fix. (Note, Part of discussion is about: isn't it better to use SizeT and IntPtrT in such places? |
@funny-falcon adding type aliases for integers which will probably change between platforms probably isn't something we want to do, as unlike C our integers don't automatically convert (a good thing). We already have that issue with some C types (for example, the bigint PR that broke on 32bit), lets not spread it around the stdlib too. I agree with @asterite's suggestion of what to do entirely. |
I'll send a PR to fix all of this later today. |
@RX14 |
Sent PR: #4960 |
Following lines certainly lead to wrong behavior on 64bit platforms with large arrays cause of
#to_u32
.crystal/src/pointer.cr
Line 245 in 46e9d81
crystal/src/pointer.cr
Line 258 in 46e9d81
crystal/src/pointer.cr
Line 499 in 46e9d81
BTW, why Crystal has neither
size_t
norintptr_t
equivalent? Some places usesUInt64
, some usesUInt32
(like this one). It is just... infantile.For example, Go defines
int
to bessize_t
anduint
to besize_t
, and hasintptr
anduintptr
(though, looks like on all supported platforms they have same size toint
).Having platform dependent
int
has profit in low-level programming, and dis-convenient for application level programming, so it certainly should not be default type.But still any place that deals with low-level memory handling should operate on platform dependent types/aliases instead of raw
UInt32
and/orUInt64
. This bogus lines are just tip of iceberg.The text was updated successfully, but these errors were encountered: