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
THRIFT-5766: Replace std::endl with "\n" #2943
Conversation
Looks good to me, albeit I do not have a strong opinion with respect to this change. I guess its a matter of personal taste whether |
(Personally)I don't think it is a matter of taste. I am also bringing up C++ Core Guidelines SL.io.50 (PS Which Bjarne commented on himself).
I would argue if it was only aesthetic why was the overload added in the first place... PS: I am probably passionate about the wrong things, shoot down the PR if this is 'out of scope' for this repo |
I doubled down and applied the changes to the whole codebase in my fork @ CJCombrink#1 |
Both the default constructor and operator== implementations reference certain member functions of the class' members. As an example, the default constructor references (i.e., "uses") the default constructors of its members. If a class contains a std::vector<Foo>, and Foo has only been *forward*- declared (which happens often in Thrift-generated code), this creates undefined behavior: The std::vector specification states that as long as Foo is an incomplete type, it is fine to reference std::vector<Foo>, but not any members (such as its default constructor). Thus, we must defer our default constructor's implementation (which references the default constructor of std::vector<Foo>) to a point where Foo is a complete type. That is the case in the .cpp file. The same holds for operator==.
Well we are certainly on the same page when it comes to In any case, I'm ok with the PR, but without a strong opinion pro or con on my side :-) |
That line was introduced intentionally in all generators. You may look up git and JIRA history and find out why, including the whole debate about why this is a good change, before removing it. I would also argue that forcing people into the literal inclusion of "\n" by removing the above most certainly will not be respected by people. Simply because nobody will think about it and just use endl instead, which due to the removal effectively results in the exact opposite of what is intended. You are setting it up for failure IMHO.
Not quite. Using std::endl is bad practice for the reasons linked above. But we're not doing that at all. That is the whole point why we have that endl constant, so nobody falls into that trap by accident. |
@Jens-G 11 Years later I am hoping that at least we can get to a point where sanity is restored and bad practices are not encouraged/entertained in such important code bases. PS: I come from a background where juniors used I am saying this again, I realise I am passionate about the wrong things thus I will not take offence if this/these PR(s) is/are declined, but I might keep stating the point :P
Depends on perspective: I see it as: "why do you need flushing" and my editor (VS Code with no custom modification) highlights |
+1 Go on then, change all the files and add a comment to the ticket, to put an end on this fruitless discussion. Question remains, why bad practice can't be fixed where it belongs - by properly deprecating
Usually deprecation and removal teaches quite well.
Agree, I wasn't fully aware of it. PS: Waiting for the great Rust rewrite, to save more walls. |
8471840
to
274ed34
Compare
I Updated this PR with replacing Do I still need to create a JIRA ticket for this change? I did request a user already thus waiting for that. |
@@ -221,11 +221,11 @@ void t_cl_generator::package_def(std::ostream &out) { | |||
} | |||
out << ")"; | |||
} | |||
out << ")" << endl << endl; | |||
out << ")\n\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in cases like this, the usage of endl
/std::endl
makes it much more obvious how many lines we are adding while \n
being part of the longer string just meshes everything together.
I'd suggest still explicitly adding every \n
individually, like this:
out << ")\n\n"; | |
out << ")" << "\n" << "\n"; |
but I don't feel strongly either way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fishy Thanks for the review and feedback.
Although I do understand the suggestion I specifically went through the effort to combine these. It does sort of stand out, but some editors color the \n
different and I deem that good enough. I find myself looking at the generated code much more often compared to the generator code thus there I quickly see how much (or few) newlines are added.
If there is enough pushback against the combination I can revert that combination change and (force)push the updates.
I don't think speed matters that much but I guess calling the operator<<
multiple times, more than the needed amount of time, would have a performance and speed implication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm slightly with @fishy here, as my comment in #2943 (comment) was actually going in the same direction: Having dedicated calls to << "\n"
jumps much more to the eye and conveyes how many newlines are added.
If you would be willing to change that, to make every newline jump out more, I'm two thumbs up for this PR! But without that change, I'm still ok to merge, albeit with minor hesitation...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@emmenlau Thank you again for the feedback.
I think there is enough reason to put back the << "\n
thus I will put in the effort (tonight) to 'revert' that change.
@CJCombrink from my point of view, everything else is good, thanks a lot for the nice work! The build failures are a continuous nightmare. The best you could do (and this is what I typically do) is check them individually, and see if the error seems related. Often builds fail because some third party dependency package can not be installed in some build machine, and those are the obvious ones to ignore. The others are harder, for those you can just compare the latest master build status with yours, to see if "you" broke it, or the person before you... In any case, we will also take a look at those before merging, but its great if you validate as much as you can upfront... |
44c4c59
to
b1abdc3
Compare
I updated the branch to use |
FYI the lib-java-kotlin failure in CI is being addressed in #2945 |
@fishy I think I have done what I can. I did check the test, master vs my changes for the parts that my environment is set up for and I don't see any regression. I have also compared the generated code for the unit tests with those against master and see no difference. What else can I do and what are the next steps for this PR? |
@CJCombrink sorry I'm in some family emergency and won't have time to review it any further for the next few weeks. None of my comment is blocking anyways :) Mario, Jens, and/or others should be able to guide you through the process. |
b1abdc3
to
12cdfa5
Compare
- Moves away from the bad habid of using endl which is known to flush - Remove references to endl and replace with line break
12cdfa5
to
ac117f7
Compare
I did some thinking... Or maybe just make the changes in the generators. I did go all the way with all other files, but baby steps might be the best or safest course of action. PS: I started a new ticket: THRIFT-5772 and if I have to choose I would rather have energy put there compared to this change, although this would be nice to have (in the C++ generator :P ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plus some files were totally missed
- contrib\fb303\TClientInfo.cpp
- lib\cpp\src\thrift\async\TEvhttpClientChannel.cpp
- lib\cpp\src\thrift\async\TEvhttpServer.cpp
- lib\cpp\src\thrift\transport\TFileTransport.cpp
- lib\cpp\test\concurrency\ThreadManagerTests.h
- lib\cpp\test\concurrency\TimerManagerTests.h
- lib\cpp\test\concurrency\Tests.cpp
Most of the missing single lines are cerr
outputs. I mean, if we want to save walls, we should be more consequent and include cerr
outputs as well, maybe doing the flush explicitly if needed. Or would cerr
be the exception from the rule that endl
is generally evil?
That's right but I'm fine in this particular case. If you could just add the commits re above changes at the end, that would make followup review easier for me. I will squash them before merge myself. |
Any news here? |
Hi Sorry, I was busy with a few other things. |
- PR feedback
- Braced init is a habit
- PR Review feedback - Initially skipped cerr but after some reading, cerr will flush after every << thus endl can also be avoided.
Initially I thought it might be good to keep cerr to flush. After your comment I did some thinking and reading and I see |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks! Two minor bugs left though.
- Picked up in review
@Jens-G Thank you for your effort and meticulous attention to the details |
nice work @CJCombrink and (as usually) @Jens-G ! |
Replaced usage of
endl
with\n
directlystatic const string endl = "\n"
(removed)[skip ci]
anywhere in the commit message to free up build resources.Reference to my comment here