Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

C-fags

Name: Anonymous 2011-06-25 16:08

What would be the best way to implement flags in C?
Bit-fields, enums, defines, etc. I've seen arguments for all three so I'm asking you, mighty /prog/, to resolve this problem.

inb4 every /prog/ meme in existence

Name: Anonymous 2011-06-25 16:10

Read SICP.I'm not a faggot.

I like to use enums, but it's really just up to you. Bit-fields are only useful if you actually have fields larger than one bit. It's really just personal preference.

Name: Anonymous 2011-06-25 16:32

*fags
Tsk. Back to /b/ please.

Name: Anonymous 2011-06-25 16:39

>>3
Nigger. Fuck off and die.

Name: Anonymous 2011-06-25 17:03

>>3,4
[/b]polecat kebabs[/b] to the two of you.

>>2
Alright, so if I had an arbitrary number of conditions some input should satisfy, would it make more sense to do something like this?

prepare for quickly written PIG DISGUSTING code:


#define FLAG1 = 01
#define FLAG2 = 02
#define FLAG3 = 04
// ...

// ...
unsigned char my_flags;
if (some_condition)
   my_flags |= FLAG1 | FLAG2;
if ((my_flags & FLAG1) == FLAG1)
   // FLAG1 high
if ((my_flags & FLAG2) == FLAG2)
   // FLAG2 high
if ((my_flags & FLAG3) == FLAG3)
   // woops, FLAG3 is low


Looks kind of ugly, so I'm wondering if there's a better way.

Name: Anonymous 2011-06-25 17:03

self-fix
polecat kebabs

Name: Anonymous 2011-06-25 17:06

>>5-6fuck you autistic nigger

Name: Anonymous 2011-06-25 18:19

Name: Anonymous 2011-06-25 18:21

>>5,6
The standard is m.i.o.u by the way.

Name: Anonymous 2011-06-25 18:21


#define FLAG1 1>>0
#define FLAG2 1>>1
#define FLAG3 1>>2
#define FLAG4 1>>3

#define SET_FLAG(FLAG, VAR) (VAR |= (FLAG))
#define UNSET_FLAG(FLAG, VAR) (VAR &= (~(FLAG)))
#define TOGGLE_FLAG(FLAG, VAR) (VAR ^= (FLAG))
#define CHECK_FLAG(FLAG, VAR) ((VAR) & (FLAG))

unsigned int my_flags;
// set FLAG1 in my_flags to high
SET_FLAG(FLAG1, my_flags);
// set multiple flags
SET_FLAG(FLAG2 | FLAG3, my_flags);
// set FLAG1 in my_flags to low
UNSET_FLAG(FLAG1, my_flags);
// toggle FLAG3
TOGGLE_FLAG(FLAG3, my_flags);
// toggle multiple flags
TOGGLE_FLAG(FLAG1 | FLAG4, my_flags);
// check flags
if(CHECK_FLAG(FLAG1, my_flags)) {
  // FLAG1 is high
} else if(CHECK_FLAG(FLAG3 | FLAG4, my_flags))
  // FLAG3 and FLAG4 is high
} else if(!CHECK_FLAG(FLAG2, my_flags)) {
  //FLAG2 is NOT high
}

Name: Anonymous 2011-06-25 18:21

Just typedef an enum to a flag_t.

Name: Anonymous 2011-06-25 18:21

>>10
god damn it wrong bitshift, should be <<

Name: Anonymous 2011-06-25 18:54

>>10
mixing logical and bitwise operations
always evaluates to true if any flag is set

Name: Anonymous 2011-06-25 18:59

>>13
wat

Name: Anonymous 2011-06-25 19:10

>>10
Using macros to hide the imaginary complexity of bitwise operations is considered harmful. Every C programmer who isn't a bungling amateur knows what the bitwise operators do, and preprocessor macros only serve to increase complexity and reduce programmer comprehension by increasing verbosity. The operators are already quite terse and are easily grokked by the C and C++ programming communities.

Name: Anonymous 2011-06-25 19:15

>>5
The ugliness is in the eye of the beholder. Learn to do it that way in C/C++ and if you ever get a job doing C/C++ programming, you will not be hated by your coworkers.

There are also struct/class bit-fields, but different compilers have different packing semantics, generate non-optimal code, nor is it as portable between different target architectures due to machine word alignment differences. Hence, they are usually not used all that much.

Name: Anonymous 2011-06-25 20:26


/* anus.h
 */
#ifndef ANUS_H__
#define ANUS_H__

enum {
    ANUS1 = (1 << 0),
    ANUS2 = (1 << 1),
    ANUS3 = (1 << 2),
    ANUS4 = (1 << 3)
};

char *hax(int);

#endif /* ANUS_H__ */


/* anus.c
 */
#include <stdio.h>
#include <stdlib.h>

#include "anus.h"

char *hax(int anii) {
    char *s;

    if (!(s = malloc(20)))
        return "back to the imageboards";

    sprintf(s, "%s%s%s%s",
               anii & ANUS1 ? "=__= " : "",
               anii & ANUS2 ? "^__^ " : "",
               anii & ANUS3 ? "v__v " : "",
               anii & ANUS4 ? "-__-" : "");

    return s;
}


/* main.c
 */
#include <stdio.h>

#include "anus.h"

int main(void) {
    puts(hax(ANUS4 | ANUS2));

    return 0;
}

Name: Anonymous 2011-06-25 22:13

>>17
Finally, a non-shitty (pun intended) post by the anus poster. Thanks anus guy.

Name: Anonymous 2011-06-26 2:33

I use bit fields when I want to pretend to be efficient but really don't care that it will use more memory and be slower than packing by hand.

Name: Anonymous 2011-06-26 8:15


}

// utilities
bool has_bits() const
{
return _value != 0;
}

bool has_bits(const bitwise_enum<Enum>& other) const
{
return (operator&(other)).has_bits();
}

size_t bits_count() const
{
unsigned long int v(_value);
size_t result(0);

while( v>0 )
{
result++;
v &= v - 1;
}

return result;
}
};


//Nonmember operators:
template <class Enum>
inline bitwise_enum<Enum> operator | (Enum value, const bitwise_enum<Enum>& e)
{
return e | value;
}

template <class Enum>
inline bitwise_enum<Enum> operator & (Enum value, const bitwise_enum<Enum>& e)
{
return e & value;
}

template <class Enum>
inline bitwise_enum<Enum> operator ^ (Enum value, const bitwise_enum<Enum>& e)
{
return e ^ value;
}


template <class Enum>
inline bitwise_enum<Enum> operator | (Enum a, Enum b)
{
return bitwise_enum<Enum>(a) | bitwise_enum<Enum>(b);
}

template <class Enum>
inline bitwise_enum<Enum> operator & (Enum a, Enum b)
{
return bitwise_enum<Enum>(a) & bitwise_enum<Enum>(b);
}

template <class Enum>
inline bitwise_enum<Enum> operator ^ (Enum a, Enum b)
{
return bitwise_enum<Enum>(a) ^ bitwise_enum<Enum>(b);
}

#endif

Name: Anonymous 2011-06-26 8:16

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

   

/*
bitwise_enums: A type-safe 1-file library for doing bitwise operations.
Copyright (C) 2008 Daniel Gutson, FuDePAN

bitwise_enums is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>;.

*/

#ifndef BITWISE_ENUMS_H
#define BITWISE_ENUMS_H


template <class Enum>
class bitwise_enum
{
unsigned long int _value;
public:
typedef unsigned int Bits;

// CONSTRUCTORS:
bitwise_enum(Enum init_value)
: _value(init_value)
{}

bitwise_enum()
: _value(0)
{}

bitwise_enum(const bitwise_enum<Enum>& other)
: _value(other._value)
{}

// UNARY OPERATIONS:
bitwise_enum<Enum> operator ~() const
{
return bitwise_enum<Enum>(~_value);
}


unsigned long int value() const
{
return _value;
}

bitwise_enum<Enum>& self_revert()
{
_value = ~_value;
return *this;
}

bitwise_enum<Enum>& clear()
{
_value = 0;
return *this;
}

// OPERATIONS with integrals:

unsigned long int operator >> (Bits bits) const
{
return _value >> bits;
}

unsigned long int operator << (Bits bits) const
{
return _value << bits;
}

// OPERATIONS BETWEEN bitwise_enums:
bitwise_enum<Enum>& operator |= (const bitwise_enum<Enum>& other)
{
_value |= other._value;
return *this;
}

bitwise_enum<Enum>& operator &= (const bitwise_enum<Enum>& other)
{
_value &= other._value;
return *this;
}

bitwise_enum<Enum>& operator ^= (const bitwise_enum<Enum>& other)
{
_value ^= other._value;
return *this;
}

bitwise_enum<Enum> operator | (const bitwise_enum<Enum>& other) const
{
bitwise_enum<Enum> ret(*this);
return (ret |= other);
}

bitwise_enum<Enum> operator & (const bitwise_enum<Enum>& other) const
{
bitwise_enum<Enum> ret(*this);
return (ret &= other);
}

bitwise_enum<Enum> operator ^ (const bitwise_enum<Enum>& other) const
{
bitwise_enum<Enum> ret(*this);
return (ret ^= other);
}

bitwise_enum<Enum>& operator = (const bitwise_enum<Enum>& other)
{
_value = other._value;
return *this;
}

bool operator == (const bitwise_enum<Enum>& other) const
{
return _value == other._value;
}

bool operator != (const bitwise_enum<Enum>& other) const
{
return ! operator==(other);

Name: Anonymous 2011-06-26 9:05

>>20-21
Use code tags you cunting jew.

Name: Anonymous 2011-06-26 9:12

Name: Anonymous 2011-06-26 9:46

>>17
Memory leaks poop.

Name: Anonymous 2011-06-26 11:54

>>24
Hard to avoid, after years and years of excessive anal gaping sessions.

Don't change these.
Name: Email:
Entire Thread Thread List