RIOT icon indicating copy to clipboard operation
RIOT copied to clipboard

`counted_by` attribute

Open carl-tud opened this issue 6 months ago • 6 comments

Could we start annotating buffers in unions, structs, and function signatures with __counted_by to indicate what field or parameter indicates the buffer's minimum guaranteed size/capacity/count?

https://people.kernel.org/gustavoars/how-to-use-the-new-counted_by-attribute-in-c-and-linux

TL;DR: Clang 18, GCC 15, backwards-source-compatible via macro, see below.

// C
void fill_array_with_indices(uint8_t* __counted_by(count) buffer, size_t count) {
  for (size_t i = 0; i < count; ++i) {
    buffer[i] = i;
  }
}
// __counted_by tells compiler: "buffer has at least count bytes"

struct aspa_record {
	// ...
	size_t provider_count;
	uint32_t provider_asns[] __counted_by(provider_count);
       // __counted_by tells compiler: "provider_asns has at provider_count elements"
};

fallback:

#ifndef __counted_by
#  if __has_attribute(__counted_by__)
#    define __counted_by(member)  __attribute__((__counted_by__(member)))
#  else
#    define __counted_by(member)
#  endif
#endif

The counted_by attribute is also used throughout the linux kernel.

Benefits:

  • Improved compiler diagnostics: safer code,
  • optional runtime checks on flexible array members
  • increased compatibility with higher-level languages when importing C e.g., Swift imports the function above as f(buffer: Span<UInt8>) (nonescapability, memory safety, exclusivity checks) instead of f(buffer: UnsafePointer<UInt8>, capacity: CInt) (unsafe). Maybe someone really familiar with Rust knows a similar technique for Rust's C interface?
  • future documentation generators may use this information for slightly better output

carl-tud avatar Jun 16 '25 13:06 carl-tud

This sounds like a good proposal. Are there any drawbacks or downsides you could think of?

crasbe avatar Jun 25 '25 12:06 crasbe

We talked about this in the Maintainer Coordination Call and you can go adhead and introduce this feature. It would be nice if you could add some documentation to the wiki or the Doxygen docs about it too, so it won't be overlooked when new code is added.

Do you have specific plans where to use it?

crasbe avatar Jun 27 '25 11:06 crasbe

We talked about this in the Maintainer Coordination Call and you can go ahead and introduce this feature.

Great.

This sounds like a good proposal. Are there any drawbacks or downsides you could think of?

If you introduce this retroactively, you may need to rearrange initialization logic so that the count/size/length properties are initialized before the respective member. (btw, the naming of count vs size vs len vs length vs num is completely off in RIOT.)

It would be nice if you could add some documentation to the wiki or the Doxygen docs about it too, so it won't be overlooked when new code is added.

I am going to add a note to the coding convention. How strict do you think we should be? Should new code generally use __counted_by everywhere? I am asking because it feels quite strict for a feature with no immediate impact, but adoption is going to suffer if it's optional. So in RFC lingo SHOULD?

Do you have specific plans where to use it?

unicoap. And a little sEcReT sIdE pRoJeCt (Embedded Swift application, RIOT underneath), which I am very, very likely not going to have the time for.

carl-tud avatar Jul 04 '25 16:07 carl-tud

I don't think it should be made mandatory, more like "(strongly) recommended to use, but no reason for rejection if not used".

crasbe avatar Jul 07 '25 12:07 crasbe

This would probably also be a good task for a student project. Combining this with a number of other modern compiler features and an evaluation how effective those tools where to find bugs it might even be enough meat for a BSc thesis?

I think @OlegHahm, @mguetschow, @crasbe, and @jmgraeffe are working with students in RIOT 😉

maribu avatar Sep 14 '25 15:09 maribu

Yeah that would help a lot, actually. I currently have to deal with a lot of logistic and organizational overhead.

carl-tud avatar Sep 26 '25 18:09 carl-tud