wrapper to make anonymous enums proper types - c

I have some typedef'd enums that are included from c-code, i.e. they are available in the form
typedef enum {FOO=3, BAR=5} my_enum;
and I would like use it in C++ code in a typesafe manner while leaving the enum names (FOO and BAR) and values (3 and 5) and their association unmodified.
Are there any best practices or patterns like template wrappers, that can be recommended to accomplish that, say in C++11 or higher?

In C++11 onwards you can declare these types as an enum class to get the type safety, but you must qualify usages with the name of the enum.
enum class my_enum {
FOO=3,
BAR=5
};
void my_func(my_enum e) {
}
int main() {
my_enum test_enum = my_enum::FOO;
my_func(test_enum);
}
If we changed the above definition of test_enum to my_enum test_enum = FOO; we'd get the error:
13:23: error: 'FOO' was not declared in this scope

It seems as if a
using
declaration works; at least the following compiles:
#include <iostream>
typedef enum{A=0, B=1, C=2} my_enum;
typedef enum{H=0, I=1, J=2} your_enum;
using namespace std;
using my_wrapper = my_enum;
using your_wrapper = your_enum;
int g(my_wrapper w)
{
return (int)w-10;
}
int g(your_wrapper w)
{
return (int)w+10;
}
int main() {
my_wrapper b=my_wrapper::B;
your_wrapper j=your_wrapper::J;
cout << g(b) << "\n";
cout << g(j) << "\n";
}

Related

Use Macro define for declaring multiple version structure in C

I'm trying to solve a problem about a protocol which has multiple version.
Its structure version will continually extend, like the following snippet, the 1.1.2 version may come.
Original:
#include <stdio.h>
#include <stdint.h>
typedef struct GetReading {
uint8_t val;
} GetReading_T;
int main()
{
GetReading_T instaince = {0};
instaince.val = 0x12c;
printf("%02x\n", instaince.val);
return 0;
}
After:
#include <stdio.h>
#include <stdint.h>
#define MULTI_S(NAME, VERSION) \
typedef struct NAME##_##VERSION {
#define MULTI_E(NAME, VERSION) \
} NAME##_##VERSION##_t;
MULTI_S(GetReading, 1_1_0)
uint8_t val;
MULTI_E(GetReading, 1_1_0)
MULTI_S(GetReading, 1_1_1)
uint16_t val;
MULTI_E(GetReading, 1_1_1)
/*
typedef struct GetReading_1_1_0 {
uint8_t val;
} GetReading_1_1_0_t;
typedef struct GetReading_1_1_1 {
uint16_t val;
} GetReading_1_1_1_t;
*/
typedef union GetReading {
GetReading_1_1_0_t v110;
GetReading_1_1_1_t v111;
} GetReading_T;
int main()
{
GetReading_T instaince = {0};
instaince.v111.val = 0x12c;
int type = 1;
if(type == 1) {
printf("%04x\n", instaince.v111.val);
} else if (type == 2) {
printf("%02x\n", instaince.v110.val);
}
return 0;
}
I just wonder if this macro technic is too hard to read and maybe redundant because it can achieve the same by declaring directly. And I found it difficult to warp the macro with the current implementation.
Is there any better practice to solve this kind of problem by C/C++?
Consider using the macro only to generate a name for the structure.
Moreover you can leave the structures untagged because there is alias for them. It would be easier to parse by a human.
#define MULTI(NAME, VERSION) NAME##_##VERSION##_t
typedef struct {
uint8_t val;
} MULTI(GetReading, 1_1_0);
typedef struct {
uint16_t val;
} MULTI(GetReading, 1_1_1);
typedef union GetReading {
MULTI(GetReading, 1_1_0) v110;
MULTI(GetReading, 1_1_1) v111;
} GetReading_T;
Is there any better practice to solve this kind of problem by C/C++?
I strongly recommend using code generation instead of C macros or C++ templates.
Use a script or program to generate the different versions of your protocol. It will be cleaner, easier to understand, faster to compile and easier to maintain.
You can even commit the generated headers so that you only pay the generating price once!

Clang/LLVM 9 and 10 SIGSEGV for inline static class members. Bug?

Using inline static class members in Clang gives me unexpected behaviour when the member is another class/struct:
https://godbolt.org/z/mbH6k7
// std=c++17
#include <iostream>
struct A {
double a = 42;
A() { std::cout << "A()" << std::endl; }
};
inline static A a{}; // No problem
namespace N {
inline static A a{}; // No problem
}
struct B {
B() { std::cout << "B()" << std::endl; }
inline static double d; // No problem with built-in types
A& a1 = N::a; // No problem
inline static A a2 = N::a; // No problem
inline static A a3{}; // <-- Problem here!
};
B b1;
inline static B b2;
int main() {
return 0;
}
Expected output, works in Clang 8.0.0, gcc, msvc:
A()
A()
A()
B()
B()
Actual output for Clang 9.0.0 and onwards: 139 (SIGSEGV).
Is this a bug, or what am I missing?
This sounds like a pretty cut-and-dry bug to me:
Per [class.static.data]
An
inline static data member may be defined in the class definition and may specify a brace-or-equal-initializer.
Your code conforms to this:
struct B {
// ...
inline static A a3{};
};

Autogenerating documentation from gcc preprocessor

I have some C code which has static initializers with values that are derived from macros. These intializers are essentially my code's external API. I am looking for a way to autogenerate documentation for my code so that the initialization values would be easily visible.
For example, below is a very simplified C program
#include
typedef unsigned int u32;
#define Q 5
#define W 7
#define BaseNum 0x1000
#define CalculateNumber(x) (BaseNum + x)
#define SomeOtherCalc(x,y) (x<<y)
typedef struct
{
u32 a;
} foo;
typedef struct
{
foo f;
} bar;
static const bar myVar[] =
{
{
.f = {
.a = CalculateNumber(SomeOtherCalc(Q,W))*sizeof(u32),
},
},
{
.f = {
.a = CalculateNumber(SomeOtherCalc(W,Q))*sizeof(u32),
},
},
};
void main(void){}
Given that program, I would like to get autogenerated documentation which says that
The variable myVar has two elements
The number of bytes that the .f field consumes
The value of the .f.a field for each element in myVar
I can get some of that information directly from GCC using gcc -E, but it doesn't completely resolve the value of .f.a nor the sizeof() into a number. Any ideas on how I can get what I'm looking for (preferably without using Doxygen)?

Inlined Setter and Getter functions in C

In C++ I can have a getter function declared inline in a header file:
class Cpp_Example
{
public:
unsigned int get_value(void)
{ return value;}
private:
unsigned int value;
};
By including this header file, client methods and functions can use the getter function to access a private variable.
I'm looking to model this concept in the C language:
hello.h:
#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
inline void Print_Hello(void)
{
extern const char hello_text[32];
puts(hello_text);
}
inline void Print_Value(void)
{
extern unsigned int value;
printf("Value is: %d\n", value);
}
#endif // HELLO_H
hello.c:
const char hello_text[32] = "Hello World!\n";
static unsigned int value = 5U;
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "hello.h"
int main(void)
{
Print_Hello();
Print_Value();
// puts(hello_text);
return EXIT_SUCCESS;
}
I get a linker error from gcc:
$ gcc -o main.exe main.c hello.c
/tmp/cc41ZB8H.o:main.c:(.rdata$.refptr.value[.refptr.value]+0x0): undefined reference to `value'
collect2: error: ld returned 1 exit status
Is there a way to have an inline function (in a header file) access a static variable in another translation unit?
Or is there a way to implement an inlined getter function?
I'm using IAR Embedded Workbench, ARM7TDMI processor on an embedded platform.
The gcc compiler is used to testing concepts on the PC.
Edit 1: Background
I'm looking to optimize getter calls that are inside a critical section. The objective is to reduce the time spent in the critical section.
Edit 2: No Globals
The Coding Guidelines our shop uses states no global variables.
Also, this system is an RTOS running MicroCOSII.
First of all, the same way you have private variables in C++, you probably mean to have private variables for a struct rather than global. With that assumption, here's one model you can use:
/* some_type.h */
struct some_type
{
int public_data;
void *privates;
};
struct some_type_privates
{
char hello[32];
int value;
};
inline const char *get_hello(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->hello;
}
inline int get_value(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->value;
}
/* similarly for setters */
The same way that your private variables and their getters and setters are in the header file, you can do it in C, too.
On the side, I'd like to recommend not to try coding C++ in C. While C++ likes to complicate things a lot to prevent the idiot from breaking something, C on the other hand trusts the programmer has some degree of intelligence. Whether these assumptions are justified are not the matter of discussion. But what I mean to say is that the spirit of C is not to hide a variable so that the programmer doesn't mistakenly access it.
That said, this is how you would normally make a struct in C:
struct some_type
{
int public_data;
char hello[32]; /* read only */
/* internal */
int value;
};
(with enough documentation of course) which tells any programmer that she shouldn't write over hello but can freely read it (what you were trying to achieve by an inline getter). It also tells that value is private so the programmer shouldn't read or write it.
You can see this in many POSIX functions that take or return a struct. Some that don't need to control the access let you freely modify the struct, such as stat. Some that do need to check the input have setters, such as pthread_attr_*.
You need to remove the static keyword. static definitions are local to the compilation unit.
As Shabbas wrote, it doesn't really work that way in C.
The keyword inline implies static, even if the compilers doesn't actually inline it. If it is such a short function, it will probably inline it. But the point is, if it would not be static, it could not even consider inlineing it, as the function would need to be visible externally, it would need an address, which an inlined function doesn't have.
Since it is local in your compilation unit, it can only work on stuff known inside that compilation unit. Thus you need to say something about that value variable, much like you do need to mention it in the C++ header as well, only in C there is no such thing as private .
You can not have Inlineing and data hiding in the same case, neither in C, nor in C++.
Assuming you mean for global, statically-allocated variables you can do this:
In Example.h:
#ifndef Example
#define Example
extern int getValue();
#endif
In Example.c
#include "Example.h"
static int value;
inline int getValue() {
return value;
}
// All the functions in Example.c have read/write access
In UsesValueExample.c
#include "Example.h"
// All the functions in UsesValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
If you want to get fancy and force all code to access through a getter and setter, e.g. if the variable is volatile and you want to heavily encourage all the methods to use a local cache of the variable to avoid the overhead of accessing the volatile, then:
In VolatileExample.h:
#ifndef VolatileExample
#define VolatileExample
extern int getValue();
#endif
In VolatileExample.c
#include "VolatileExample.h"
void setValue(); // Forward declaration to give write access
// All the functions in VolatileExample.c have read/write access via getters and setters
void addToValuesAndIncrementValue(int const values[], int const numValues) {
int value = getValue(); // Cache a local copy for fast access
// Do stuff with value
for (int i = 0; i < numValues; i++) {
values[i] += value;
}
value++;
// Write the cache out if it has changed
setValue(value);
}
// Put the definitions after the other functions so that direct access is denied
static volatile int value;
inline int getValue() {
return value;
}
inline void setValue(int const newValue) {
value = newValue;
}
In UsesVolatileValueExample.c
#include "VolatileExample.h"
// All the functions in UsesVolatileValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
Here is a pattern I've been using to hide global variables.
Inside some header file, such as module_prefix.h, you declare the following:
typedef int value_t; // Type of the variable
static inline value_t get_name(void) __attribute__((always_inline));
static inline void set_name(value_t) __attribute__((always_inline));
static inline value_t get_name(void) {
extern value_t module_prefix_name;
return module_prefix_name;
}
static inline void set_name(value_t new_value) {
extern value_t module_prefix_name;
module_prefix_name = new_value;
}
/* Note that module_prefix_name is *no longer* in scope here. */
Then of course you have to define module_prefix_name in some compilation unit, without the static keyword, as discussed above, e.g. in module_prefix.c you have the following:
#include "module_prefix.h"
value_t module_prefix_name = MODULE_PREFIX_NAME_INIT_VALUE;
This is essentially the same pattern that Thomas Matthews tried to use, drilling down to the essence and making sure that the compiler inlines the functions always and does not unnecessarily generate explicit function bodies. Note the use of module_prefix as poor man's name spaces.

iterator header: can't use begin or end with array as argument, c++11

1>c:\users\indira\documents\visual studio 2012\projects\cpppremier\cpppremier\ch1.cpp(2060): error C3861: 'begin': identifier not found
1>c:\users\indira\documents\visual studio 2012\projects\cpppremier\cpppremier\ch1.cpp(2060): error C3861: 'end': identifier not found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
#include <iostream>
#include <string>
#include <cstddef>
#include<array>
#include<vector>
#include <iterator>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int *pbeg = begin(ia), *pend = end(ia);
cout << "Elements in arr: " << endl;
for (int *pbeg; pbeg != pend; ++pbeg)
{
*pbeg = 0;
cout << *pbeg << endl;
}
getchar();
getchar();
return 0;
}
I don't understand why this is not working.I'm trying to use the iterator header to use begin and end functions defined in that header.
The code has the iterator header. The functions are taking the array as argument, since array is not a class type...
I tried this in visual studio 2013, and in compileonline.com c++11.
begin and end are functions in the std namespace, so you should introduce them with using, or qualify them (eg. as std::begin).
You don't need this when your argument is itself a std type: argument-dependent lookup finds them in that case - but ADL doesn't work when your arguments are primitive types, or anything else not itself defined inside namespace std.
Here's some sample code to explain how name lookup works in this case. Just because something is visible in a translation unit, doesn't mean it's a valid match.
namespace test {
struct Type { };
void foo(Type);
void bar(int);
}
int main() {
/*
Type t; <-- NO: Type is declared but not visible for name lookup
nl.cpp: In function ‘int main()’:
nl.cpp:11:5: error: ‘Type’ was not declared in this scope
nl.cpp:11:5: note: suggested alternative:
nl.cpp:3:12: note: ‘test::Type’
*/
test::Type u; // OK: the qualified name can be looked up
foo(u); // OK: argument-dependent lookup means test is considered
/*
bar(1); <-- NO: int isn't part of namespace test
nl.cpp:22:10: error: ‘bar’ was not declared in this scope
nl.cpp:22:10: note: suggested alternative:
nl.cpp:6:10: note: ‘test::bar’
*/
test::bar(1); // OK: explicitly tell the compiler where to look
}
You can either introduce names from a different namespace into your current one with using (you already did this with std::string etc.), or explicitly qualify them.

Resources