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

Fix warning on 4.10 #766

Closed
aantron opened this issue Feb 25, 2020 · 10 comments
Closed

Fix warning on 4.10 #766

aantron opened this issue Feb 25, 2020 · 10 comments

Comments

@aantron
Copy link
Collaborator

aantron commented Feb 25, 2020

See https://travis-ci.org/ocsigen/lwt/jobs/654080430#L430.

Made slightly difficult by that Bytes_val was added in 4.06.

@rwmjones
Copy link
Contributor

For reasons I'm not very clear on this is actually an error (not a warning) for the Fedora build. It may be that the Fedora build system is adding some hardening flags which causes this.

@rwmjones
Copy link
Contributor

I suggested changing String_val to Bytes_val, but as you point out that macro was only added in 4.06. It could be easier to simply cast the String_val to (char *).

@aantron
Copy link
Collaborator Author

aantron commented Feb 25, 2020

I just added the cast in a branch, will merge after CI. By the way, the original patch filename weakly implied that this was caused by Lwt 5.1.2. In fact, it has been in Lwt for a very long time. 5.1.2 is just the first release after OCaml 4.10 was released. It is OCaml 4.10 that caused this.

@aantron
Copy link
Collaborator Author

aantron commented Feb 25, 2020

I'll retag the 5.1.2 release, since it's stalled in opam's CI anyway.

@hannesm
Copy link
Contributor

hannesm commented Feb 25, 2020

the issue with a cast from const char * to char * is that this is undefined behaviour in C AFAICT -- an alternative if some #ifdef dance and use Bytes_val for < 4.06, String_val for >= 4.06.

@rwmjones
Copy link
Contributor

I guess in the future if the OCaml compiler decided to allocate strings in the text segment, this could actually fail. I don't think it does at the moment.

@aantron
Copy link
Collaborator Author

aantron commented Feb 25, 2020

Do you have a reference for why and what exactly is UB? Is the actual cast operation UB, or is the argument about the effect of treating the underlying data "unsafely?"

Also note that, at the moment,

#define String_val(x) ((const char *) Bp_val(x))
#define Bp_val(v) ((char *) (v))

Is there a C implementation on which (char*)(const char*)(char*)(v) isn't the same as just (char*)v? I'll try the #ifdef version anyway, but I am pretty skeptical about the cast being invalid.

aantron added a commit that referenced this issue Feb 25, 2020
@aantron
Copy link
Collaborator Author

aantron commented Feb 25, 2020

@hannesm See commit attached above.

@hannesm
Copy link
Contributor

hannesm commented Feb 25, 2020

I don't have an authoritative reference, sorry. But https://en.wikipedia.org/wiki/Const_%28computer_programming%29#Loopholes_to_const-correctness says "Writing into a const variable this way may work as intended, but it causes undefined behavior and seriously contradicts const-correctness".

Thanks.

@aantron
Copy link
Collaborator Author

aantron commented Feb 25, 2020

This part of the Wikipedia article needs some editing attention :p

What ultimately convinced me is @rwmjones' last comment about the representation of strings potentially changing. Even if their storage doesn't move to a read-only section like .text or .rodata, the definition of String_val might change in the future, and diverge from Bytes_val, even despite the fact that we have Bytes.unsafe_of_string and Bytes.unsafe_to_string. So, it's better to just use the macros.

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

No branches or pull requests

3 participants