#Is writing uninitialized memory to file Undefined Behaviour? If so, why?

1 messages · Page 1 of 1 (latest)

rare valve
#

Let's assume I write memory via fwrite. I found myself being yelled by valgrind, as I was writing some uninitialized memory to file.

However, in my solution, writing to file was not sequential - these fragments would be overwritten later, so I didn't bother zero-ing them. Is that UB?

grave muskBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For more information use !howto ask.

wicked harness
#

You mean something like this

char a;
// Open a file to write
// Write to file e.g.
ofstream.write(a, sizeof(char));
ofstream << a;
#

if you're using fprintf, you can further assistance in #1013104018739974194 or #c-help-text

void stump
#

I’m going to assume write/frwite is being used here not fprintf

#

This is almost certainly the class of UB where it’s pedantically UB but every compiler will always do what you expect

rare valve
#

I assumed so, but can't file the exact wording determining it's UB (I would still assume so)

#

And yes, I meant fwrite, I didn't have enough coffee today ^^"

serene quiver
#

OOC is there a cost to zeroing the memory before writing to a file?

#

ST you intentionally removed the zero line to save something?

tiny canopy
#

what are you writing how exactly?

rare valve
#

It is not a practical question, more language-lawyery

serene quiver
#

fair yep

lavish lark
#

out of curiosity I went to take a look at a version of the c11 standard I found online, and honestly I don't wanna set foot there again

#

standard wording should revolve around indeterminate values https://eel.is/c++draft/basic.indet
indeterminate values are allowed to exist and be evaluated and propagate but only between objects with the "magic types" of unsigned char and std::byte
the C++ standard defers to the C standard for basically everything in cstdio (https://eel.is/c++draft/cstdio.syn#1)
and looking at the C standard (urgh) it is explicitly stated that each "byte" of the object is treated as an unsigned char and processed by successive calls to fputc (http://port70.net/~nsz/c/c11/n1570.html#7.21.8.2)
now the signature of fputc is int fputc(int c, FILE *stream); so each of the unsigned char has to be converted to an int

now the big question, if you consider that conversion from unsigned char to int should follow the C++ standard then this is UB, as converting an unsigned char with an indeterminate value to something that isn't an unsigned char or a std::byte is intended to be UB
if you consider you should follow the C standard there since C++ deferred to C, this is where I consider reading the C standard "not-a-great-experience"

#

a little bit of ctrl-f for indeterminate in that version of the C standard yields

The behavior is undefined in the following circumstances:

now the weird thing to me is "why would you restrict the UB-ness only with stuff that has automatic storage duration

#

because allocated storage duration is distinct from automatic storage duration, and that's what object created with malloc and co are, and malloc pretty explicitly produces object that have indeterminate value (http://port70.net/~nsz/c/c11/n1570.html#7.22.3.4)
as far as I can tell, assignment from an allocated storage duration object with indeterminate value would propagate that indeterminate value (http://port70.net/~nsz/c/c11/n1570.html#6.5.16.1) so now you can kinda have indeterminate galore everywhere, and somehow it's only UB if you use the value from an automatic storage duration object

#

or maybe the exception is required because attempting to overwrite the value of an object with allocated storage duration counts as using the value of that object?

grave muskBOT
#

This question thread is being automatically closed. If your question is not answered feel free to bump the post or re-ask. Take a look at !howto ask for tips on improving your question.