For example I have:
int boo[8];
boo[1] = boo[3] = boo[7] = 4;
boo[0] = boo[2] = 7;
boo[4] = boo[5] = boo[6] = 15;
How I should type it as constant values? I saw similar question but it didn't help me.
EDIT:
One more question what about if boo with indexes 0 1 3 4 5 6 7 is constant but boo[2] is not? is it possible to do it?
Is this what you are looking for?
const int boo[] = { 7, 4, 7, 4, 15, 15, 15, 4 };
Get a non-const pointer to one entry in the array like this:
int * foo = (int*)&boo[2];
One not so elegant solution may be:
const int boo[8] = {7,4,7,4,15,15,15,4};
Another solution may be:
int boo_[8];
boo_[1] = boo_[3] = boo_[7] = 4;
boo_[0] = boo_[2] = 7;
boo_[4] = boo_[5] = boo_[6] = 15;
const int * boo = boo_;
Related
trying to convert some C++ code into C, I'm working with binary data and need to use a C equivalent of this:
enum GssipFlags : uint16_t
{
SPARE0 = 1,
SPARE1 = 2 * SPARE0,
SPARE2 = 2 * SPARE1,
SPARE3 = 2 * SPARE2,
REQ_MSG = 2 * SPARE3,
DISCONNECT = 2 * REQ_MSG,
CONNECT = 2 * DISCONNECT,
INVALID_DATA = 2 * CONNECT,
CMD_REJECT = 2 * INVALID_DATA,
HANDSHAKE = 2 * CMD_REJECT,
NAK_MSG = 2 * HANDSHAKE,
ACK_MSG = 2 * NAK_MSG,
ACK_REQ = 2 * ACK_MSG,
RESYNC = 2 * ACK_REQ,
MODE = 2 * RESYNC,
READY = 2 * MODE
};
enum GssipMessageIDs : uint16_t
{
CCCCCCCC = 1,
RECEIVER_ID_MSG = 2,
BUFFER_BOX_STATUS_REQUEST_MSG = 3,
SETUP_DATA_5031 = 4,
WARNING_MSG = 5,
TIME_TRANSFER = 6
};
enum GssipWarningMsgIDs : uint16_t
{
EXTERNAL_POWER_DISCONNECT = 17,
SELF_TEST_OK = 8,
AAAAA = 9,
BBBBB = 10
};
Everything I've tried hasnt worked. the main aspect of this I need is for everything to be uint16_t
You have one standard option and two potential options depending on your compiler and what "I'm working with binary data and need to use a C" means (memory usage?, speed?, etc):
This has been already commented, the use of structs with the type you are looking for:
typedef struct {
uint16_t SPARE0;
...
} GssipFlags_t;
GssipFlags_t a = {
.SPARE0=1
...
};
If you are trying to reduce the size of enums, take advantage of the compiler (if available) and use -fshort-enums.
Allocate to an enum type only as many bytes as it needs for the declared range of possible values. Specifically, the enum type is equivalent to the smallest integer type that has enough room.
__attribute__((packed)), in order to remove the padding added between members (which may do things slower due to the cost of accessing to unaligned data).
If you don't mind about the size and your only concern is to compile C++11 code with a C compiler (which might produce the same output than adding -fshort-enums), just do:
enum GssipFlags {
SPARE0 = 1
...
};
Items 2, 3 and 4 don't explicitly create members with uint16_t type, but if this is a XY problem, they provide different solutions depending on your real issue.
I have std::string with value 1T23:
How can I get x = 1, y = 2, z = 3;
I tried:
int x = std::atoi(&myString.at(0));
int y = std::atoi(&myString.at(2));
int z = std::atoi(&myString.at(3));
but it returned: x = 0, y = 23, z = 3?
You can do this:
int x = std::stoi(myString.substr(0, 1));
int y = std::stoi(myString.substr(2, 1));
int z = std::stoi(myString.substr(3, 1));
If it's all sigle digits, it could be simple:
int x = myString.at(0) - '0';
int y = myString.at(2) - '0';
int z = myString.at(3) - '0';
Of course, you need to handle potential exceptions (e.g. myString has less than 4 characters). at operator can throw std::out_of_range.
Also consider what if the interested chars are not digits in myString.
std::atoi will treat the input as a char const *, and try to convert from that position to the null-terminator.
In this case
int x = std::atoi(&myString.at(0));
the string 1T23 is converted to an int. Since this conversion is not possible, you get the result of 0.
For the other cases:
int y = std::atoi(&myString.at(2)); // converts "23" to 23
int z = std::atoi(&myString.at(3)); // converts "3" to 3
You can get the actual numbers by using std::stoi, and using the appropriate substrings. Alternatively, since you only want single digits, you could index into the string, and subtract '0'. The other answers show how to do this exactly.
So I came across this question somewhere:
Case 1:
int a;
a = 1, 2, 3;
printf("%d", a);
Case 2:
int a = 1, 2, 3;
printf("%d", a);
The explanation says:
The second case gives error because comma is used as a separator, In first case = takes precedence over , so it is basically (a=1), 2, 3;
But I want to ask why does = not take precedence over , in Case 2?
It is not just a question of precedence, but rather a question of the language grammar: the = in both cases is not the same operator:
in the declaration int a = 1, 2, 3;, the = token introduces an initializer which cannot be a comma expression. The , ends the initializer and the compiler issues an error because 2 is not a valid identifier for another variable.
in the statement a = 1, 2, 3;, a = 1, 2, 3 is an expression, parsed as ((a = 1), 2), 3 because = has higher precedence than ,. = is the assignment operator whose right hand side is an expression, this assignment is the left operand of a comma operator , followed by a constant expression 2, a = 1, 2 itself the left operand of the final , operator whose right operand is 3. The statement is equivalent to ((a = 1), 2), 3);, which simplifies into a = 1;.
This
int a = 1, 2, 3;/* not a valid one */
is wrong because since = has higher priority, so it become int a = 1 internally and there is no name for 2 and 3 thats why this statement is not valid and cause compile time error.
To avoid this you might want to use
int a = (1, 2, 3); /* evaluate all expression inside () from L->R and assign right most expression to a i.e a=3*/
And here
int a;
a = 1,2,3;
there are two operator = and , and see man operator. The assignment operator = has higher priority than comma operator. So it becomes a=1.
a = 1,2,3;
| L--->R(coma operator associativity)
this got assigned to a
for e.g
int x = 10, y = 20,z;
z = 100,200,y=30,0; /* solve all expression form L to R, but finally it becomes z=100*/
printf("x = %d y = %d z = %d\n",x,y,z);/* x = 10, y = 30(not 20) z = 100 */
z = (100,200,y=30,0); /* solve all expression form L to R, but assign right most expression value to z*/
Inside variable declarations (as case 1) comma are used to declare several variables, for example:
int a,b=2,c=b+1,d; //here only b and c were initialized
An statement in C/C++ could be a list of comma separated expressions (this is what happens in case 2):
a=b+1, c+=2, b++, d = a+b+c, 3, d; //these are expressions, remember one literal is an expression too!!!
NOTE : comma (,) is a compile time operator,
from my side their is Four cases that you can come across :
case 1
int a = 1, 2, 3; // invalid case cause too many initializers
case 2
int a = (1, 2, 3); // valid case
/* You can expand this line as a :
1;
2;
int a = 3;
*/
case 3
int a;
a = 1, 2, 3; // valid case
/* You can expand this line as a :
a = 1; // expression 1
2; // expression 2
3; // expression 3
*/
case 4
int a;
a = ( 1, 2, 3);// valid case
/* You can expand this line as a :
1; // expression 1
2; // expression 2
a = 3; // expression 3
*/
In above cases in place of 1, 2, 3 we can use any valid expression in C, explore more!!
Is it possible to have clang-format align variable assignments in columns? For example:
int someInteger = 42;
std::string someString = "string";
const unsigned someUnsigned = 42;
#define SOME_INTEGER 42
#define SOME_STRING_LITERAL "string"
#define SOME_CONSTANT 42
enum Enum {
ONE = 1,
TWO = 2,
THREE = 3,
FOUR = 4,
FIVE = 5,
SIX = 6,
SEVEN = 7
};
is more readable than:
int someInteger = 42;
const unsigned someUnsigned = 42;
std::string someString = "string";
#define SOME_INTEGER 42
#define SOME_STRING_LITERAL "string"
#define SOME_CONSTANT 42
enum Enum {
ONE = 1,
TWO = 2,
THREE = 3,
FOUR = 4,
FIVE = 5,
SIX = 6,
SEVEN = 7
};
I realize that it may not be practical for clang-format to always do this, but when code as already been manually formatted like said code, it would be nice for clang-format to leave the formatting in place.
It looks like 3.7 supports something like this (haven't tested yet).
From the docs
AlignConsecutiveAssignments (bool)
If true, aligns consecutive assignments.
This will align the assignment operators of consecutive lines. This will result in formattings like code int aaaa = 12; int b = 23; int ccc = 23; endcode
(sic)
Clang-format does not have any option to do this.
If you want to tell clang-format to leave certain lines alone, you can make it do so with // clang-format off and // clang-format on comments.
I tested it using https://github.com/mattga/ClangFormat-Xcode/tree/clang_3.7 which is branch of ClangFormat-Xcode supporting 3.7.
I could format a = 9999; type list as I wanted by option
AlignConsecutiveAssignments = true
. But definitions were not aligned.
Is there any indication to align them?
For macros: looks like you will be able to accomplish this once clang 10 is released, by adding AlignConsecutiveMacros: true to you .clang-format
https://reviews.llvm.org/D28462
you can use this options:AlignConsecutiveMacros: true
ref:https://clang.llvm.org/docs/ClangFormatStyleOptions.html
support llvm version: >=10.0
This question already has answers here:
Non-unique enum values
(8 answers)
Closed 8 years ago.
See the following code:
enum ChunkIndex {
ZeroIndex = 0,
SpecializedIndex = ZeroIndex,
SmallIndex = SpecializedIndex + 1,
MediumIndex = SmallIndex + 1,
HumongousIndex = MediumIndex + 1,
NumberOfFreeLists = 3,
NumberOfInUseLists = 4
};
ChunkIndex index0 = (ChunkIndex) (0);
ChunkIndex index3 = (ChunkIndex) (3);
ChunkIndex index4 = (ChunkIndex) (4);
You see that there exists at least two enum values that equal to 0.
The same as 3.
What will happen when cast 0 to enum ChunkIndex?
The same question with 3.
The code above is from jdk8/openjdk/hotspot/src/share/vm/memory/metaspace.cpp line 83 and its above 7 lines.
[Strictly regarding C++]
You're going to have that 0-converted-to-enum value matching both the 0 values of the enum
ChunkIndex index0 = (ChunkIndex) (0);
if(index0 == ChunkIndex::ZeroIndex)
cout << "hello"; // Gets printed
if(index0 == ChunkIndex::SpecializedIndex)
cout << "world"; // Gets printed
This is also valid with C++11 typesafe enums
enum class ChunkIndex
As PaulR noted, enums are usually syntactic sugar to render integer values (whatever their value is) more meaningful to readers.