emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: cc-mode uniform initialization support


From: Daniel Colascione
Subject: Re: cc-mode uniform initialization support
Date: Sat, 29 Aug 2015 17:54:58 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0

On 08/20/2015 09:49 AM, Alan Mackenzie wrote:
> Hello, Daniel.
> 
> On Wed, Aug 19, 2015 at 11:36:11AM -0700, Daniel Colascione wrote:
>> Recent versions of C++ support using {} to indicate an initialization
>> value. For example,
> 
>>   1 int foo{5};
>>   2 int bar = {5};
>>   3 mumble_t mumble{
>>   4  foo,
>>   5    bar
>>   6 };
>>   7 return {mumble, foo}; // Type inferred from function declaration
> 
> Yes.
> 
>> Working with code written in this style is a nightmare right now because
>> cc-mode recognizes line 4 as defun-block-intro, leading to line 5 being
>> indented spuriously, since cc-mode thinks it's a statement continuation.
>> In reality, the construct starting at line 3 is a brace list, but
>> there's no syntactic clue to tell us that.
> 
> How about the fact that there's no argument list (in parens)?  Is that
> not sufficient to distinguish a brace list from a defun?

I don't think so. In the _same_ codebase, we have code that looks like this:

SCOPE_EXIT {
  statement1,
    statement1_cont;
  statement2;
};

and

foo("foo", something{
  item1,
  item2});

Lots of codebases have SCOPE_EXIT-like things: the Linux kernel, for
example, has a bunch of custom LIST_FOREACH-like macros, so we can't
just check whether the word before the "{" is a keyword.  The check for
whitespace before the "{" in my patch is a really hacky heuristic for
distinguishing the two cases. It works for the coding style I work with,
but it's not very good in general.

It's unfortunate that C++ overloaded "{" this way, since it makes it
hard to locally determine what's going on syntactically.

How about these rules? We'll assume we have a brace-list if:

1) we see "({" outside a macro definition, as in "foo({bar,qux})", or

2) we see a "{" preceded by "return", as in "return {1,2}" (say, in a
function declared to return std::pair<int,int>), or

3) we see a "{" preceded by a ",", as in "foo(foo, {bar})" (do we need
to look for operators generally?), or

4) we see a "{" preceded by an identifier not in ALL CAPS.

---

Do we need a separate c++11-mode so users can choose between c++-mode
with the old heuristics and the new one with the hacks I've described?
#1 and #4 might be controversial.

>> (We can, of course, look for an "=", but an "=" is no longer required
>> for a brace list.)
> 
>> I don't see a way around needing to use awful heuristics to distinguish
>> the cases. Does anyone have a better idea? Keep in mind that code like
>> this is common too:
> 
>>   foo({
>>     abc,
>>     def
>>   });
> 
>> And plenty of people define macros that accept blocks:
> 
>>   MY_FOREACH {
>>     statement1;
>>     statement2;
>>   }
> 
> I've had a look at your patch, and after correcting it (so that at the
> indicated lines, the result of the `looking-at' is returned rather than
> the result of `backward-char' (which is nil)), tried it out.  It does
> indeed appear to work on the example code you gave.
> 
> However, it gives lots of errors in the test suite, including in some
> C++ test files (namely decls-15.cc, inexprstat-2.cc, inher-9.cc), so it
> needs some refinement.  There are also a few niggly details where the
> patch isn't quite correct, but they should be easy enough to correct.

Thanks.

>

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]