[Development] [Feature] Q_INFO: Annotations for classes, methods, properties and enums

Thiago Macieira thiago.macieira at intel.com
Thu Sep 12 03:47:12 CEST 2013


On quarta-feira, 11 de setembro de 2013 22:19:33, Stefan Merettig wrote:
> This would be ambiguous to the reader. That's why I always stressed
> that the
> macro is *prepended* to whatever it applies to:
> 
>    Q_ANNOTATE("foo" = "bar") class MyClass { ...

I'm fine with that, provided it matches a place where the C++11 attributes can 
be placed in a class declaration.

So:
$ clang -xc++ -std=c++11 -fsyntax-only - <<<'[[foo]] class X {};'
<stdin>:1:1: error: an attribute list cannot appear here
[[foo]] class X {};
^~~~~~~
1 error generated.

$ gcc -xc++ -std=c++11 -fsyntax-only - <<<'[[foo]] class X {};'
<stdin>:1:15: warning: attribute ignored in declaration of ‘class X’ [-
Wattributes]
<stdin>:1:15: note: attribute for ‘class X’ must follow the ‘class’ keyword

There we go, the matter is settled: the annotation must appear after the class 
keyword, before the class name. An attribute placed before the "class" keyword 
applies to a variable of that class type:

	[[foo]] class X {} x, y; // [[foo]] applies to x and y

Let me see if I can decrypt for you N2761 (attributes rev6), plus the 
amendments in N3067 which moved a few positions around:

	[[foo]] class X {} x, y; // [[foo]] applies to x and y
	class [[foo]] X {} x, y; // applies to type X
	class X [[foo]] {} x, y; // ill-formed
	class X {} [[foo]];      // ?? #1
	class X {} [[foo]] x, y; // ?? #2
	class X {} x [[foo]], y; // applies to variable x, but not y
	class X {} x, y [[foo]]; // applies to variable y, but not x

	[[foo]] void f(), g();  // applies to both functions f() and g()
	void [[foo]] f(), g();  // ?? #3
	void f [[foo]] (), g(); // applies to function f(), but not g()
	void f() [[foo]], g();  // ?? #4
	void f(), g [[foo]] (); // applies to function g(), but not f()
	void f(), g() [[foo]];  // ?? #4

struct S {
	[[foo]] S();	// applies to the constructor S
	[[foo]] ~S();	// applies to the destructor S
}

It seems that ?? cases 1 and 2 apply to "class X", but not to type X. GCC 
prints this warning:
  warning: attribute ignored in declaration of ‘class X’

Cases 3 and 4 seem to be allowed and they apply to a type specifier. In all 
four cases, I have no clue what they're used for.

> It's beyond me why we would like to set the name explicitly in the
> macro.
> Just think of overloaded methods .. Sounds like fun. I just want a
> uniform
> API for this, both in the Qt API and in the header file. While placing
> the
> annotation data in the Q_PROPERTY is a violation of this thought, I can
> live
> with it as long it's the only exception. 

Unfortunately, the problem is that there's no semi-colon or braces separating 
Q_PROPERTYs from one another and from other declarations. So there's no way to 
cleanly separate declaration from one another except for the parentheses 
themselves.

Therefore, the annotation must come inside the Q_PROPERTY.

> Though I want to point out that it's
> confusing that Q_PROPERTY 'appends' this information while everything
> else
> has it prepended. Appending the annotation data to everything is too
> hard to
> read (Think of classes, would you ever look at the end to find a
> annotation?)
> and sometimes even dangerous:
>    void myFunc () Q_INFO(...) { .. }
>    void myFunc () { .. } Q_INFO(...)

The second one is a clear-case: the ending brace ended the declaration. So 
that Q_INFO is applying to the *next* thing that appears:

    void myFunc() { } Q_INFO("a" = "b")
    void myOtherFunc() { }

The annotation belongs to myOtherFunc.

As for the first case, see above.

> Just think of future fun moments in #Qt because people put their
> annotations
> at the wrong position. A 'always prepend' rule is pretty simple to
> communicate on the other hand, even with a exception for Q_PROPERTY.

Understood, but since C++11 set the rule, people need to deal with it. I'd 
much rather we explain once for both types of annotations than explain how 
it's different.

> Maybe I'm the only one with that problem, but the positions of C++11
> attributes
> and their implications confuses me all the time. That's why I
> explicitly stated
> that Q_INFO/Q_ANNOTATE is always prepended, that is, it's in front of
> the
> declaration itself. Nowhere else, simply because IMO it's the only
> readable
> version.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20130911/9a79fec4/attachment.sig>


More information about the Development mailing list