News for hackers. Stuff that matters.
Re:Show HN by jstimpfle on Saturday December 03, 2022 @10:19AM (#33844082)
This is hilarious. SIZE_MAX is at least as large as the largest string that you can put in your address space anyway. Which is what the strlen() API already assumes.

That, plus you'd be a fool to store a huge string in this way in any case.

Re:Show HN by Someone on Saturday December 03, 2022 @11:16AM (#33844505)
> SIZE_MAX is at least as large as the largest string that you can put in your address space / memory anyway.

Not necessarily. A 64-bit system could give processes an address space that’s significantly larger than half the full 64-bit address space and have an allocator that allows you to allocate a block of more than SIZE_MAX bytes (malloc takes a size_t, but you can use calloc)

Re:Show HN by jstimpfle on Saturday December 03, 2022 @11:35AM (#33844696)
This doesn't make sense to me. You can't "allocate" more than SIZE_MAX bytes by definition. If you take "allocate" to mean "make it available in the process's address space", that is.
Re:Show HN by unwind on Saturday December 03, 2022 @03:36PM (#33847052)
Are you sure?

The calloc() [1] function mentioned above takes two values of type size_t, and allocates their product bytes.

I'm on mobile without (!) the C99 draft spec but at least the man page gives no such restriction.

[1] https://linux.die.net/man/3/calloc

Re:Show HN by mek6800d2 on Saturday December 03, 2022 @04:38PM (#33847649)
I read something about this recently, somewhere, maybe HN. Specifically, in calloc(), what is done and what should really be done if the multiplication overflows. As will happen, for example, if you try to calloc() two elements of size SIZE_MAX, when SIZE_MAX is the maximum representable unsigned integer value on the machine. So, I don't think calloc() is available or intended as a way to circumvent malloc()'s size restriction.
Re:Show HN by Someone on Saturday December 03, 2022 @06:39PM (#33848716)
I stand corrected. Initially, I thought that, even if it calloc can’t, an OS could provide a different way to obtain a pointer to a memory region that’s larger than SIZE_MAX.

However, the standard says (https://en.cppreference.com/w/c/types/size_t):

“size_t can store the maximum size of a theoretically possible object of any type (including array).”

and (https://en.cppreference.com/w/c/language/pointer):

“Pointer is a type of an object that refers to a function or an object of another type, possibly adding qualifiers. Pointer may also refer to nothing, which is indicated by the special null pointer value.”

⇒ pointers must either be null or point to an object, and objects aren’t larger than SIZE_MAX, so I think having a pointer pointing to a block larger than SIZE_MAX violates the standard.

Re:Show HN by jstimpfle on Saturday December 03, 2022 @06:51PM (#33848836)
> pointer pointing to a block larger than SIZE_MAX violates the standard.

it's simply not possible, by definition.

Re:Show HN by jstimpfle on Saturday December 03, 2022 @06:41PM (#33848732)
I mean, explain first how you plan to allocate more address space than is addressable?

calloc returns NULL when it's not possible to satisfy the request.

Re:Show HN by ahepp on Saturday December 03, 2022 @01:11PM (#33845747)
Isn't size_t defined as being able to fit the largest possible data allocation?
Re:Show HN by Karellen on Saturday December 03, 2022 @01:56PM (#33846196)
size_t is unsigned, right? ssize_t is the signed version?

On a quick test on my 64-bit system, a C program doing `printf("%zu\n", SIZE_MAX);` outputs 18446744073709551615, which looks like (2^64)-1 to me.

Or is there a thing in the standard that says this isn't always the case?

Re:Show HN by arcticbull on Saturday December 03, 2022 @04:38PM (#33847657)
ssize_t is a weird one, the only negative value it is guaranteed to store is -1.

> The type ssize_t shall be capable of storing values at least in the range [-1, {SSIZE_MAX}].

[1] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sy...

Re:Show HN by jstimpfle on Saturday December 03, 2022 @08:22PM (#33849525)
size_t need only be large enough to cover the (virtual) address space. It's up to hardware and OS to decide how much addressable space you get. I believe current systems can use only the low 48 bits of 64-bit pointers. However that number is likely to be increased in the future and OSes would be unwise to define size_t as something smaller than 64 bits.
Re:Show HN by mananaysiempre on Tuesday December 06, 2022 @06:15AM (#33878114)
No, ssize_t is not the signed version. As best as I can tell, the only things POSIX says about ssize_t is that[1] it is an integer type that can hold integer values in [-1, SSIZE_MAX], where[2] SSIZE_MAX ≥ _POSIX_SSIZE_MAX = 32767, not that it should have any particular relation to size_t. In the standard, it is used for byte counts in I/O, like the return value of read() (traditionally int), for the return value of strfmon() and strfmon_l() (OK I guess, though the C standard stuck with int for *printf()), and for the argument to swab() (wat).

Note that neither is ptrdiff_t guaranteed to be that signed version, or to hold any possible value in the domain of size_t or (strictly speaking) any possible object size. Both GCC and Clang assume the latter, though, and can miscompile[3] code that relies on (e.g.) malloc() succeeding for sizes > 2^31 on a 32-bit system.

[1] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sy...

[2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/li...

[3] https://trust-in-soft.com/blog/2016/05/20/objects-larger-tha...

Re:Show HN by pjmlp on Saturday December 03, 2022 @01:09PM (#33845726)
Indeed, you just need to forget to put a terminator to get a nice memory dump.