This is because replacing it with emplace_back could cause a leak of this pointer if emplace_back would throw exception before emplacement (e.g. not enough memory to add new element).".
In the case of push_back/emplace_back for the same type, there should be no performance changes, however emplace_back might generate more template instantiations slowing down compilation.
There is also topic of using insert/emplace for maps showing that map.emplace can be slower than map.insert. I would not want to distinguish between emplace for maps and emplace for vectors,
so I believe using emplace for constructed temporaries, even if there would be some slightly performance regression, looks simpler and more readable.
I am happy to change to write changes to LLVM coding standards document, but I firstly would like to see what community thinks about it.
NOTE that I don't propose running clang-tidy and modifying whole codebase. It might happen some day, but we firstly need to agree that these changes are better.
There are also other checks from performance and misc that I would like to enable. Some of them are already enabled (all misc), but because they are more about finding bugs, I would like to narrow discussion only to modernize.
From yesterday discussion, Daniel Berlin proposed using emplace_back everywhere to make code easier to maintain. I think it is valid argument, but I believe it would reduce readability.
There is also other reason - emplace_back can't take arguments of some types like bitfields, NULL, static member. Using emplace can also lead to memory leak in case of smart ptrs"This is because replacing it with
emplace_backcould cause a leak of this pointer ifemplace_backwould throw exception before emplacement (e.g. not enough memory to add new element).".
From yesterday discussion, Daniel Berlin proposed using emplace_back everywhere to make code easier to maintain. I think it is valid argument, but I believe it would reduce readability.Just to be clear; I proposed not trying to switch uses back and forth without real data, and to come to some agreement about what should be written in the first place, preferably based on real data, and then, switching in some organized fashion, not just randomly :)IE Either have a clear coding standard and enforce it, or leave uses alone one way or the other without some demonstration that it actually matters.I would *personally* prefer to just use emplace_back everywhere, and not try to switch between the two, without demonstration of real benefit.(i'd also accept the other way, use push_back everywhere, and not try to switch between the two, without demonstration of real benefit).This preference is based on a simple truth: People suck at deciding when to use one or the other. Yes, i know how to use it and when to use it. Lots of our types are cheaply movable, etc, so you probably won't see any performance difference even when using them "right". People have enough style/etc issues without having to try to think hard about this.So that isn't what I would necessarily propose for LLVM.For LLVM, my answer would be "either make tool do what we want, force use of tool, or be consistent and obvious with what we want and then fix it if it leads to performance issue"
There is also other reason - emplace_back can't take arguments of some types like bitfields, NULL, static member. Using emplace can also lead to memory leak in case of smart ptrs"This is because replacing it with
emplace_backcould cause a leak of this pointer ifemplace_backwould throw exception before emplacement (e.g. not enough memory to add new element).".This seems, IMHO, not a useful argument for LLVM since it does not try to use exception based error handling to recover.
_______________________________________________
cfe-dev mailing list
cfe...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
On Dec 29, 2016, at 5:54 AM, Daniel Berlin <dbe...@dberlin.org> wrote:From yesterday discussion, Daniel Berlin proposed using emplace_back everywhere to make code easier to maintain. I think it is valid argument, but I believe it would reduce readability.Just to be clear; I proposed not trying to switch uses back and forth without real data, and to come to some agreement about what should be written in the first place, preferably based on real data, and then, switching in some organized fashion, not just randomly :)IE Either have a clear coding standard and enforce it, or leave uses alone one way or the other without some demonstration that it actually matters.I would *personally* prefer to just use emplace_back everywhere, and not try to switch between the two, without demonstration of real benefit.(i'd also accept the other way, use push_back everywhere, and not try to switch between the two, without demonstration of real benefit).This preference is based on a simple truth: People suck at deciding when to use one or the other. Yes, i know how to use it and when to use it. Lots of our types are cheaply movable, etc, so you probably won't see any performance difference even when using them "right". People have enough style/etc issues without having to try to think hard about this.
So that isn't what I would necessarily propose for LLVM.
For LLVM, my answer would be "either make tool do what we want, force use of tool, or be consistent and obvious with what we want and then fix it if it leads to performance issue”
There is also other reason - emplace_back can't take arguments of some types like bitfields, NULL, static member. Using emplace can also lead to memory leak in case of smart ptrs"This is because replacing it with
emplace_backcould cause a leak of this pointer ifemplace_backwould throw exception before emplacement (e.g. not enough memory to add new element).".This seems, IMHO, not a useful argument for LLVM since it does not try to use exception based error handling to recover.
I'm a bit confused by this whole discussion.
clang-format is neither mandated (by documentation) nor enforced (by any infrastructure/automation) for use in the LLVM project that I know of.
It's convenient, and in review people may reasonably ask authors to consider running it, etc - but we have no system that requires or checks for that. Might be nice, might not be.
It sounds like even if clang-format were mandated - we mostly accept that such a mandate is forward-looking, and that we don't want/intend to reformat the entire existing codebase. So I imagine the same would apply to clang-tidy (we wouldn't expect to tidy the entire codebase - we'd just use clang-tidy as advisory for any new changes as we do with clang-format) - so I don't think it'd run up against Danny's protest about choosing a philosophy for wide scale changes, because there would be no wide scale changes.
All that said, I think like clang-format we should probably have a project-wide config that specifies which checks we care about - but the real impediment to adoption of those checks is a streamlined process for running them on a patch. clang-format has nice integration with my editor (vim) and source control system (git-clang-format). I have yet to discover an equally convenient place to put clang-tidy in my workflow. Without that I doubt it'll see very much adoption within the LLVM community.
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
On Dec 29, 2016, at 5:54 AM, Daniel Berlin <dbe...@dberlin.org> wrote:From yesterday discussion, Daniel Berlin proposed using emplace_back everywhere to make code easier to maintain. I think it is valid argument, but I believe it would reduce readability.Just to be clear; I proposed not trying to switch uses back and forth without real data, and to come to some agreement about what should be written in the first place, preferably based on real data, and then, switching in some organized fashion, not just randomly :)IE Either have a clear coding standard and enforce it, or leave uses alone one way or the other without some demonstration that it actually matters.I would *personally* prefer to just use emplace_back everywhere, and not try to switch between the two, without demonstration of real benefit.(i'd also accept the other way, use push_back everywhere, and not try to switch between the two, without demonstration of real benefit).This preference is based on a simple truth: People suck at deciding when to use one or the other. Yes, i know how to use it and when to use it. Lots of our types are cheaply movable, etc, so you probably won't see any performance difference even when using them "right". People have enough style/etc issues without having to try to think hard about this.I agree that “people suck at deciding”, me in the first place in the line, and that’s why I like clear and good guideline and stick to it unless "demonstration of real benefit”.I also think we can have clear guideline that are different from “always use emplace_back” or “always use push_back”, like Piotr is suggesting.
That said, I’m not convinced the relative “ugliness" of emplace_back (I’m not sure what’s ugly there, I only see it as a habit to take) vs push_back is enough to justify a set of rules to decide between the two, I’d be fine with “always using emplace_back” in the name of “simple rule is better when possible".So that isn't what I would necessarily propose for LLVM.For LLVM, my answer would be "either make tool do what we want, force use of tool, or be consistent and obvious with what we want and then fix it if it leads to performance issue”+1Ultimately whatever we do is not practical if it can’t be done by a tool.
There is also other reason - emplace_back can't take arguments of some types like bitfields, NULL, static member. Using emplace can also lead to memory leak in case of smart ptrs"This is because replacing it with
emplace_backcould cause a leak of this pointer ifemplace_backwould throw exception before emplacement (e.g. not enough memory to add new element).".This seems, IMHO, not a useful argument for LLVM since it does not try to use exception based error handling to recover.This, and also we should not write code like that (naked pointers, calling new), using make_unique<> for instance would prevent any such situation. Passing a raw pointer to a container of unique_ptr can be flagged by a tool.
—Mehdi
On Dec 29, 2016, at 11:20 AM, David Blaikie <dbla...@gmail.com> wrote:On Thu, Dec 29, 2016 at 10:04 AM Mehdi Amini via cfe-dev <cfe...@lists.llvm.org> wrote:On Dec 29, 2016, at 5:54 AM, Daniel Berlin <dbe...@dberlin.org> wrote:From yesterday discussion, Daniel Berlin proposed using emplace_back everywhere to make code easier to maintain. I think it is valid argument, but I believe it would reduce readability.Just to be clear; I proposed not trying to switch uses back and forth without real data, and to come to some agreement about what should be written in the first place, preferably based on real data, and then, switching in some organized fashion, not just randomly :)IE Either have a clear coding standard and enforce it, or leave uses alone one way or the other without some demonstration that it actually matters.I would *personally* prefer to just use emplace_back everywhere, and not try to switch between the two, without demonstration of real benefit.(i'd also accept the other way, use push_back everywhere, and not try to switch between the two, without demonstration of real benefit).This preference is based on a simple truth: People suck at deciding when to use one or the other. Yes, i know how to use it and when to use it. Lots of our types are cheaply movable, etc, so you probably won't see any performance difference even when using them "right". People have enough style/etc issues without having to try to think hard about this.I agree that “people suck at deciding”, me in the first place in the line, and that’s why I like clear and good guideline and stick to it unless "demonstration of real benefit”.I also think we can have clear guideline that are different from “always use emplace_back” or “always use push_back”, like Piotr is suggesting.I don't think Piotr is suggesting "always use push_back" but "always use push_back when it's valid" & I'd second this.
To show a simpler example:
std::unique_ptr<T> u(v);
std::unique_ptr<T> u = v;
I'd generally advocate for using copy init (the second form - it doesn't copy in this case, it moves) over direct init (the first form) because it's more legible - copy init can only execute implicit ctor operations, whereas direct init can invoke implicit and explicit operations. So from a readability perspective seeing the latter is easier than seing the former - I know the operation is further constrained to simpler/less interesting operations (eg: 'v' can't be a raw pointer in the second form, it might be (& then I have to worry about whether that's an ownership transfer that's intended), etc)
& push_back V emplace_back is the same choice - push_back means only implicit ops are used and so it's more readable
, emplace_back requires more careful attention.
I think this is a reasonably good stylistic rule - but I'm happy leaving an open to judgment for sure - there might be readability reasons that an emplace_back may work better in some cases.
I'd think of this like "else after return" - we don't have any enforcement, sometimes we make judgment about it being better (for consistency - sometimes there's a pattern such that else makes the code more readable), we haven't gone back to do any cleanup of the codebase, but it's pretty consistently applied/desired in code review.
On Dec 29, 2016, at 11:20 AM, David Blaikie <dbla...@gmail.com> wrote:On Thu, Dec 29, 2016 at 10:04 AM Mehdi Amini via cfe-dev <cfe...@lists.llvm.org> wrote:On Dec 29, 2016, at 5:54 AM, Daniel Berlin <dbe...@dberlin.org> wrote:From yesterday discussion, Daniel Berlin proposed using emplace_back everywhere to make code easier to maintain. I think it is valid argument, but I believe it would reduce readability.Just to be clear; I proposed not trying to switch uses back and forth without real data, and to come to some agreement about what should be written in the first place, preferably based on real data, and then, switching in some organized fashion, not just randomly :)IE Either have a clear coding standard and enforce it, or leave uses alone one way or the other without some demonstration that it actually matters.I would *personally* prefer to just use emplace_back everywhere, and not try to switch between the two, without demonstration of real benefit.(i'd also accept the other way, use push_back everywhere, and not try to switch between the two, without demonstration of real benefit).This preference is based on a simple truth: People suck at deciding when to use one or the other. Yes, i know how to use it and when to use it. Lots of our types are cheaply movable, etc, so you probably won't see any performance difference even when using them "right". People have enough style/etc issues without having to try to think hard about this.I agree that “people suck at deciding”, me in the first place in the line, and that’s why I like clear and good guideline and stick to it unless "demonstration of real benefit”.I also think we can have clear guideline that are different from “always use emplace_back” or “always use push_back”, like Piotr is suggesting.I don't think Piotr is suggesting "always use push_back" but "always use push_back when it's valid" & I'd second this.Define “valid”? Just that it will compile?
To show a simpler example:
std::unique_ptr<T> u(v);
std::unique_ptr<T> u = v;
I'd generally advocate for using copy init (the second form - it doesn't copy in this case, it moves) over direct init (the first form) because it's more legible - copy init can only execute implicit ctor operations, whereas direct init can invoke implicit and explicit operations. So from a readability perspective seeing the latter is easier than seing the former - I know the operation is further constrained to simpler/less interesting operations (eg: 'v' can't be a raw pointer in the second form, it might be (& then I have to worry about whether that's an ownership transfer that's intended), etc)
& push_back V emplace_back is the same choice - push_back means only implicit ops are used and so it's more readableI don’t see what’s more readable about “only implicit ctor”.
Emplace is very explicit that we intended to construct an object, I don’t understand what hurts readability here?
, emplace_back requires more careful attention.
I think this is a reasonably good stylistic rule - but I'm happy leaving an open to judgment for sure - there might be readability reasons that an emplace_back may work better in some cases.
I'd think of this like "else after return" - we don't have any enforcement, sometimes we make judgment about it being better (for consistency - sometimes there's a pattern such that else makes the code more readable), we haven't gone back to do any cleanup of the codebase, but it's pretty consistently applied/desired in code review.I have a different impression: we are actively cleaning the codebase with tidy-checks.
For instance look for `git log --author=Zelenko`.Another example is that a few months ago the entire LLDB codebase has been formatted with clang-format, after marking the specific places where it was not desirable (tables for instance) with comment to disable clang-format.
Still another way to see the consequence of this is to look at the nature of compiler errors when a programmer makes a mistake.With emplace_back, if you fail to call the constructor correctly, all of the error messages come with a layer (or many layers) of template instantiation. With push_back(T(...)), the constructor call is direct and the error messages are as well.With emplace_back, if you are converting from one type to another and the conversion fails, you again get template backtraces. With push_back, all the conversions happen before the push_back method and so the error is local to your code.
Thanks for very accurate responses.- I totally agree what Dave and Chandler said about explicit and implicit operations, this is what I meant my first email.I believe there are places likev.emplace_back(A, B);istead ofv.push_back(make_pair(A, B));bThat can make code simpler.
I think in cases like this we can leave it for judgement of contributor.
On Fri, Dec 30, 2016 at 2:08 AM Piotr Padlewski via cfe-dev <cfe...@lists.llvm.org> wrote:Thanks for very accurate responses.- I totally agree what Dave and Chandler said about explicit and implicit operations, this is what I meant my first email.I believe there are places likev.emplace_back(A, B);istead ofv.push_back(make_pair(A, B));bThat can make code simpler.Do you have examples? The only ones i can come up with are the ones where the push_back variant literally can't compile because the type isn't movable.Perhaps it would be useful to break down categories of can happen here...Case 1: there is one object already -- this is a *conversion* of a type.- If the author of the conversion made it *implicit*, then 'v.push_back(x)' just works.- If the author of the conversion made it *explicit* I would like to see the name of the type explicitly: 'v.push_back(T(x))'.
Case 2a: There is a collection of objects that are being composed into an aggregate. We don't have any interesting logic in the constructor, it takes an initializer list.- This should work with 'v.push_back({a, b, c})'- If it doesn't today, we can fix the type's constructors so that it does.- Using 'emplace_back' doesn't help much -- you still need {}s to form the std::initializer_list in many cases. Pair and tuple are somewhat unusual in not requiring them.
Case 2b: A specific constructor needs to be called with an argument list. These arguments are not merely being aggregated but are inputs to a constructor that contains logic.- This is analogous to a case called out w.r.t. '{...}' syntax in the coding standards[1]- Similar to that rule, I would like to see a *call to the constructor* rather than hiding it behind 'emplace_back' as this is a function with interesting logic.- That means i would write T(a, b, c) anyways, and 'v.push_back(T(a, b, c))' works.
[1]: http://llvm.org/docs/CodingStandards.html#do-not-use-braced-initializer-lists-to-call-a-constructorCase 3: Passing objects of type 'T' through 'push_back' fails to compile because they cannot be copied or moved.- You *must* use 'emplace_back' here. No argument (obviously).My experience with LLVM code and other codebases is that case 3 should be extremely rare. The intersection of "types that cannot be moved or copied" and "types that you put into containers" is typically small.Anyways, I don't disagree with this point with a tiny fix:I think in cases like this we can leave it for judgement of contributor.*or reviewer*. ;]I continue to think exceptions can be made in rare cases when folks have good reasons. But I expect this to be quite rare. =]
I thought we had all of those already...
> The last point is to get to consensus with
>
> push_back({first, second})
> or
> emplace_back(first ,second);
I second Chandler's opinion on this.
cheers,
--renato
On 9 January 2017 at 14:17, Piotr Padlewski via cfe-dev
<cfe...@lists.llvm.org> wrote:
> - prefer "using' instead of "typedef"
> - use default member initialization
> - use default, override, delete
> - skip "virtual" with override
I thought we had all of those already...
> The last point is to get to consensus with
>
> push_back({first, second})
> or
> emplace_back(first ,second);
I second Chandler's opinion on this.
cheers,
--renato
Are there any other comments about changing style guide?I would like to add points like- prefer "using' instead of "typedef"- use default member initializationstruct A {void *ptr = nullptr;};
(instead of doing it in constructor)- use default, override, delete- skip "virtual" with overrideThe last point is to get to consensus withpush_back({first, second})oremplace_back(first ,second);
On Mon, Jan 9, 2017 at 6:17 AM Piotr Padlewski via cfe-dev <cfe...@lists.llvm.org> wrote:Are there any other comments about changing style guide?I would like to add points like- prefer "using' instead of "typedef"- use default member initializationstruct A {void *ptr = nullptr;};(instead of doing it in constructor)- use default, override, delete- skip "virtual" with overrideThe last point is to get to consensus withpush_back({first, second})oremplace_back(first ,second);
It might be a bit noisy, but I'd be inclined to start a separate thread for each of these on llvm-dev with a clear subject line relevant to each one. So they don't get lost and some of them don't get drowned out by the discussion of others, etc.
2017-01-09 17:24 GMT+01:00 David Blaikie <dbla...@gmail.com>:On Mon, Jan 9, 2017 at 6:17 AM Piotr Padlewski via cfe-dev <cfe...@lists.llvm.org> wrote:Are there any other comments about changing style guide?I would like to add points like- prefer "using' instead of "typedef"- use default member initializationstruct A {void *ptr = nullptr;};(instead of doing it in constructor)- use default, override, delete- skip "virtual" with overrideThe last point is to get to consensus withpush_back({first, second})oremplace_back(first ,second);
It might be a bit noisy, but I'd be inclined to start a separate thread for each of these on llvm-dev with a clear subject line relevant to each one. So they don't get lost and some of them don't get drowned out by the discussion of others, etc.
Sure, I can do it, but at least now I don't see much of attention of people to any of the subject, so I would not like to start 5 empty threads.I guess as long as the thread is not getting noisy I will keep only one. Does it sound ok?
2017-01-09 16:15 GMT+01:00 Renato Golin <renato...@linaro.org>:On 9 January 2017 at 14:17, Piotr Padlewski via cfe-dev
<cfe...@lists.llvm.org> wrote:
> - prefer "using' instead of "typedef"
> - use default member initialization
> - use default, override, delete
> - skip "virtual" with override
I thought we had all of those already...
Nope, some people use it, but I still see a lot of new code with typedefs.I would like to have it written in style guide so it will be easier to convince to change in review.
On Mon, Jan 9, 2017 at 10:10 AM Piotr Padlewski <piotr.p...@gmail.com> wrote:2017-01-09 17:24 GMT+01:00 David Blaikie <dbla...@gmail.com>:On Mon, Jan 9, 2017 at 6:17 AM Piotr Padlewski via cfe-dev <cfe...@lists.llvm.org> wrote:Are there any other comments about changing style guide?I would like to add points like- prefer "using' instead of "typedef"- use default member initializationstruct A {void *ptr = nullptr;};(instead of doing it in constructor)- use default, override, delete- skip "virtual" with overrideThe last point is to get to consensus withpush_back({first, second})oremplace_back(first ,second);
It might be a bit noisy, but I'd be inclined to start a separate thread for each of these on llvm-dev with a clear subject line relevant to each one. So they don't get lost and some of them don't get drowned out by the discussion of others, etc.
Sure, I can do it, but at least now I don't see much of attention of people to any of the subject, so I would not like to start 5 empty threads.I guess as long as the thread is not getting noisy I will keep only one. Does it sound ok?
Perhaps - if no one else pipes up *shrug*
If that's the case, I'd at least suggest submitting the changes to the style guide separately with clear subject/titles so people reading commits might see/notice/discuss there.
FWIW: I'm also in favor of push_back where valid. Though I'm not sure it's so much a matter of votes, but justification, etc. As for the others - sure, they all sound good to me.
Also - once these are in the style guide there's still a separate discussion to be had about whether automated cleanup is worthwhile & how best to go about that sort of thing.
The text read "prefer", which I think it's fair. I'm opposed to any
hard rule for the sake of new-ness, consistency, or personal
preference.
If we encode all nit-rules as "prefer", then it should be more like a
guideline than a rule book, which has been our motto for everything
else.
On Mon, Jan 9, 2017 at 7:25 AM, Piotr Padlewski via llvm-dev <llvm...@lists.llvm.org> wrote:2017-01-09 16:15 GMT+01:00 Renato Golin <renato...@linaro.org>:On 9 January 2017 at 14:17, Piotr Padlewski via cfe-dev
<cfe...@lists.llvm.org> wrote:
> - prefer "using' instead of "typedef"
> - use default member initialization
> - use default, override, delete
> - skip "virtual" with override
I thought we had all of those already...
Nope, some people use it, but I still see a lot of new code with typedefs.I would like to have it written in style guide so it will be easier to convince to change in review.The last two are enforced by compiler warnings now. The second is hard because of bitfields.
On 9 January 2017 at 18:20, Reid Kleckner <r...@google.com> wrote:
> I object to the first. If you need a new type name, use a typedef. It's time
> honored and everyone, including C programmers, will know what you're doing.
> I don't understand why people push the new thing just for the sake of
> new-ness.
The text read "prefer", which I think it's fair. I'm opposed to any
hard rule for the sake of new-ness, consistency, or personal
preference.
If we encode all nit-rules as "prefer", then it should be more like a
guideline than a rule book, which has been our motto for everything
else.
cheers,
--renato
This is not correct according to the number of “should” and the imperative tone for many aspects of http://llvm.org/docs/CodingStandards.html#source-code-formatting
—
Mehdi
You mistake the tone of the documentation. There are things that
cannot be (exceptions, RTTI), things that are important to get right
(includes vs. forward declaration), things that are preferred
(c++11-isms) and things that are optional and very much depends on the
situation. The four items in the list I replied to fall into the
latter category.
The tone used for each type is appropriate to its enforcement. If you
add compiler errors or warnings, it's pretty easy to enforce.
Everything else will have varying degrees of success, and being
obnoxious about it has never been, and I hope never will be, our way.
We don't force people to run clang-format on patches, we ask when it's
ugly and people do because they believe it's a good thing. When the
formatting doesn't hurt my eyes, I don't ask for clang-format. I
certainly won't start asking people to run clang-tidy, though I'd be
happy if they did. That's personal and with the volume of commits we
have, that last thing we need is people blocking or reverting patches
because they didn't conform to personal preferences, even if they were
encoded in the coding standards.
I also strongly oppose to encoding personal preferences with a
stronger wording that it's warranted. Personal is personal. If it's
legal C++ and it's an appropriate use of the language for the case at
hand, than it's fine. I couldn't care less if you use "using" or
"typedef". I can understand both. "Prefer using" is an interesting
proposition, but refuse patches because they have "typedefs" is silly.
Honestly, my "coding standards" would be as simple as "do whatever
Scott Meyers says you should", but the LLVM one is nice, too. Unless
it's used as a weapon.
cheers,
--renato
Either one of us is mistaken, but I find yourself being fairly confident here…
Try going above the 80 cols and defend it as your personal preference in a review, and let me know how it went.
—
Mehdi
I'm only speaking from what I've seen happening in the past few years
committing and reviewing code. Our personal opinions don't change what
happened before, though they may try to change the future.
I just hope we don't become nit-pick nazis. I certainly won't become one.
I would prefer using typedefs at least for function pointers. I find either of
Sorry I fat fingered an earlier send in the previous email. I was
trying to say:
On Mon, Jan 9, 2017 at 2:52 PM, Sanjoy Das
<san...@playingwithpointers.com> wrote:
>> +1 Exactly this.
>> I don't think C programmer will not understand using. The "=" makes it much
>> simpler to read, even if it is the first time you see it, which is not the
>> case of typedef.
>>
>> typedef MyType::NestedType (*fptr)(const MyOhterType&);
>> or
>> using fptr = MyType::NestedType (*)(const MyOhterType&);
>
I would prefer to please keep using typedefs at least for function
pointers. I find either of
typedef MyType::NestedType (*fptr)(const MyOhterType&);
or
typedef int fptr(const int&);
void f(fptr* ptr) {
...
}
easier to read than the "using" declaration (especially the second
form, with the explicit `fptr* ptr`).
-- Sanjoy
Hi,
Sorry I fat fingered an earlier send in the previous email. I was
trying to say:
On Mon, Jan 9, 2017 at 2:52 PM, Sanjoy Das
<san...@playingwithpointers.com> wrote:
>> +1 Exactly this.
>> I don't think C programmer will not understand using. The "=" makes it much
>> simpler to read, even if it is the first time you see it, which is not the
>> case of typedef.
>>
>> typedef MyType::NestedType (*fptr)(const MyOhterType&);
>> or
>> using fptr = MyType::NestedType (*)(const MyOhterType&);
>
I would prefer to please keep using typedefs at least for function
pointers. I find either of
typedef MyType::NestedType (*fptr)(const MyOhterType&);
or
typedef int fptr(const int&);
void f(fptr* ptr) {
...
}
easier to read than the "using" declaration (especially the second
form, with the explicit `fptr* ptr`).
> On Jan 9, 2017, at 12:47 PM, Renato Golin <renato...@linaro.org> wrote:
>
> On 9 January 2017 at 19:04, Mehdi Amini <mehdi...@apple.com> wrote:
>> This is not correct according to the number of “should” and the imperative tone for many aspects of http://llvm.org/docs/CodingStandards.html#source-code-formatting
>
> You mistake the tone of the documentation.
Either one of us is mistaken, but I find yourself being fairly confident here…
Try going above the 80 cols and defend it as your personal preference in a review, and let me know how it went.
.png?part=0.0.1&view=1)
—
On Jan 10, 2017, at 12:33 AM, Sean Silva <chiso...@gmail.com> wrote:On Mon, Jan 9, 2017 at 12:48 PM, Mehdi Amini via llvm-dev <llvm...@lists.llvm.org> wrote:
> On Jan 9, 2017, at 12:47 PM, Renato Golin <renato...@linaro.org> wrote:
>
> On 9 January 2017 at 19:04, Mehdi Amini <mehdi...@apple.com> wrote:
>> This is not correct according to the number of “should” and the imperative tone for many aspects of http://llvm.org/docs/CodingStandards.html#source-code-formatting
>
> You mistake the tone of the documentation.
Either one of us is mistaken, but I find yourself being fairly confident here…
Try going above the 80 cols and defend it as your personal preference in a review, and let me know how it went.I doubt most reviewers will notice if you go slightly over 80 cols without some sort of automated check warning about it. W.r.t. the higher-level semantic guidelines, no reviewer keeps them all in their head. Just writing down a rule doesn't buy anything no matter how you write it down.
The real coding standard is the one that a critical mass of LLVM developers will comment on when they find something objectionable.
<download (8).png>
You can't have that certainty with guidelines.
These 4 examples are less enforceable than 80-columns or
no-tabs-2-spaces rules, despite both sets being personal. They're
clearly guidelines.
All writing it down will buy you is "prefer this, not that", but:
1. If you have a good reason to do that, please do.
2. If the surrounding code uses that pattern, and this is not a
structural change, please repeat.
3. If it makes no difference as to the clarity of the code, who cares?
The most important thing here is the reaction of the community.
Reverting patches because they don't conform to guidelines is a big
mistake. Even 80 columns violation should be fixed later, in place, by
the original committer, after post-commit review.
Blocking patches because they don't conform to personal preferences,
even if they're encoded in the coding standard as "prefer" or
"should", ignoring the other facts I mention above, is also really bad
form.
First, we don't have code stewards to clean up other people's mistakes
or preferences, not we should. This would create a culture of garbage
code, where people don't care about what they commit.
Second, we want developers to feel comfortable contributing to our
project. People DO have different cultures, preferences, levels of
comfort with the languages and the project. But they also have their
own lives and work, and can't spend months polishing small patches,
just because they're not perfect in the view of random developers in
our community. That would be extremely counter-productive and would
ultimately kill the project.
Similar behaviour has killed other OSS projects in the past, so this
is not theoretical.
All that said, I think those 4 *guidelines* are nice to have on our
coding standards. But I'm ultimately against forcing people to run
clang-tidy or blocking/reverting patches because they don't match
perfectly with the coding standards.
f(42);}where typedef int (*fptr)(const int&)works.
-- Sanjoy
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Yeah. It was confusing in the original example to have "ptr" in the name of the typedef. Usually it is more like:typedef int callback_func(void *closure);int foo(callback_func *cb) {// ...
}(though this style is pretty rare in my experience, and results in the callback_func name being a weird type that you can't assign or do other stuff with).-- Sean Silva
Can we get at least a summary of any decisions made before action is taken? I'm definitely not reading this thread in detail and I doubt others are either.
Philip