C++ Logo

std-proposals

Advanced search

Re: [std-proposals] __COUNTER__

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Sat, 24 Aug 2024 13:18:28 +0200
pt., 23 sie 2024 o 17:08 Thiago Macieira via Std-Proposals
<std-proposals_at_[hidden]> napisaƂ(a):
>
> On Friday 23 August 2024 02:09:39 GMT-7 Marcin Jaczewski via Std-Proposals
> wrote:
> > I think we have XY problem here, why do I even need `__COUNTER__` in
> > my C++ code?
> > Unique local variable? Soon we will have `_`.
> > Unique global variable? Add new keywords that will be placeholder for
> > name like `__unique_name__`.
> >
> > There is any other case where I would use `__COUNTER__`?
>
> Having a __unique_name__ identifier generator may replace __COUNTER__, but
> given that the likely only use is still through macros, I don't see the value.
> Plus it wouldn't solve the problem of ODR: unlike a preprocessor thing like
> __COUNTER__, it would be hard to standardise a language construct that knows
> which file it came from, so if the same file is #include'd from another TU, it
> generates the same identifier.
>

I now consider if a file should be even used in this?
It could be possible to deduce based on the statement how to generate
an identifier.
Let consider this case:

```
//file a.h
int __unique_name__;

//file b.cpp
namespace Foo
{
#include "a.h"
}

//file c.cpp
namespace Bar
{
#include "a.h"
}
```

Should these values have the same name?
For me even if this identifier is from the same file it should be independent.

As far I see this should work more based on immediate context than
preprocessor state
(like what was include chain).

For example, I have:

```
inline int __unique_name__ = 5;
```

Is it safe to assume that in any TU that encounters this definition in
the global namespace
it could assume this is the same object?



> There are two places in Qt code where we currently need unique identifiers, but
> neither currently need __COUNTER__. One of them is in the Q_GLOBAL_STATIC
> macro, which creates a global (namespace-scope) static variable of a unique
> type and the other is in the moc-generated code associated with each meta
> object's meta type table (a hackish solution to prevent ODR violations in case
> of types only forward-declared are fully declared elsewhere). In both cases,
> it actually turns out we have a unique identifier we could use to build another
> upon, so we could avoid __COUNTER__, respectively the name of the variable and
> the type of the class whose meta object we're creating.

How exactly does the final definition look like? If it have unique type
we could assume that if any other definition with the same type
is the same object.
Like:

```
inline SomeUniqueTypeA __unique_name__ ; //A
inline SomeUniqueTypeB __unique_name__ ; //diffrent than A
inline SomeUniqueTypeA __unique_name__ ; //same as A
```

or even:
```
//foo.h
extern SomeUniqueTypeA __unique_name__ ; //B

//foo.cpp
SomeUniqueTypeA __unique_name__ ; //same as B
```

but diffrent namespaces do not colide:

```
namespace A
{
SomeUniqueTypeA __unique_name__ ; //A
}

namespace B
{
SomeUniqueTypeA __unique_name__ ; //diffrent object to A
}

namespace
{
SomeUniqueTypeA __unique_name__ ; //each TU have its own version of this object
}
```


This could solve all typical use cases of `__COUNTER__` or
this approach could have some missing critical functionalities?

>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Principal Engineer - Intel DCAI Platform & System Engineering
>
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-08-24 11:18:40