ShieldCat
ShieldCat

Reputation: 113

Creating custom keywords in C++ using libraries

I want to create a keyword that modifies a variable during definition. Similar to how long long var; creates something different than long var;, or static int var; does something special to the variable. The question is: how can I create custom keywords that specifically modify variables during initialization.

A specific example: I currently have a library that adds a custom variable type called uint7 that is 7 bits long, 1 less than a byte. I want to have a keyword to double the size, similar to how the code long long var; creates a variable with double the size of a long variable. Specifically, I want to create a keyword "twin" so that I can use twin uint7 var; to make a 14-bit long variable. The reason I can't just make uint14 is because I want this to work on ALL variables, including int, char, bool, float, uint7, and more.

Please note, the reason I am asking this question is to understand how to create the keywords, not specifically for the uint7 or twin concept.

Upvotes: -4

Views: 113

Answers (1)

Dúthomhas
Dúthomhas

Reputation: 10028

You cannot add or change keywords in C++ (or C).

The correct way to manage types is to give them a name. The traditional way is with the typedef keyword, but other methods exist, depending on syntactical needs.

You also cannot change integer sizes directly. You can name things to give them semantic meaning useful to the programmer. For example:

typedef unsigned char  uint7;
typedef unsigned short uint14;


You can do weird stuff if you want to be more specific about how bits are handled, but this is equivalent to redefining an integer type yourself. (And I’m not convinced this is correct anyway, but it was fun to do.)

#include <iostream>

#ifdef _MSC_VER
#pragma pack(push,1)
#endif
union uint7
{
    unsigned value : 7;
    operator int () const { return value; }
    uint7 operator = ( unsigned value ) { this->value = value; return *this; }
    uint7( unsigned value ) : value{value} { }
}
#ifndef _MSC_VER
__attribute__((packed))
#endif
typedef uint7;
#ifdef _MSC_VER
#pragma pack(pop)
#endif

int main()
{
    uint7 x = 127;
    
    std::cout << x << "\n";
    
    x = x + 1;
    std::cout << x << "\n";
    
    x = x + 1;
    std::cout << x << "\n";
    
    std::cout << "size of uint7 = " << sizeof(uint7) << "\n";
}
$ clang++ -Wall -Wextra -Werror -pedantic-errors -O3 -std=c++17 a.cpp
$ ./a.out 
127
0
1
size of uint7 = 1

Notice, for example, that things like ++x and x += 1 are not defined, because I didn’t add them to the definition of uint7.

(So, don’t do this. Just use the type alias to an extant integer type and be careful how you handle its values.)

Upvotes: 4

Related Questions