How should I constructs a self-referencing struct? E.g. a binary tree?
I assumed I should do it like below, but it throws Segmentation fault: 11
import std.typecons;
struct Node {
int value;
NullableRef!Node left, right;
}
void main() {
Node n;
}
How should I constructs a self-referencing struct? E.g. a binary tree? I assumed I should do it like below, but it throws Segmentation fault: 11
A segmentation fault during compilation indicates a compiler bug. In this case, it looks like it's a regression introduced in 2.068. I'll bisect and report it, so it should be fixed in the next release. Until then, you can downgrade to DMD 2.067 or earlier, which does not exhibit this bug.
If usage of NullableRef is not imperative, you can simply use plain pointers for now:
struct Node {
int value;
Node* left, right;
}
void main() {
Node n;
}
Related
I would have posted this in the spinroot Bug Reports, but the spinroot forum is not currently accepting new users... If someone out there in charge of that is reading this, please let me in :)
Something very odd is happening when I try to use the select statement. Promela does not allow select() to be called on the field of a struct, so I have to make a temporary variable like this:
typedef someStruct {
int someField;
}
someStruct struct;
inline SetSelect() {
int temp;
select(temp: -1 .. 1);
struct.someField = temp;
}
init{
SetSelect();
}
This runs fine. I tested it and struct.someField is correctly set to either -1, 0, or 1. However, when I try to just put the inlined code straight into the init() process, I get a syntax error. The code looks like this:
typedef someStruct {
int someField;
}
someStruct struct;
init{
int temp;
select(temp: -1 .. 1);
struct.someField = temp;
}
And the error message is:
spin: select_test.pml:9, Error: syntax error saw ''-' = 45'
BUG:
Indeed, it looks like a bug for version 6.4.6 of Spin.
(The bug is fixed in version 6.4.7)
Interestingly, You can make it go away by simply writing temp : instead of temp:.
I suggest you to contact Gerard Holzmann for filing a bug report. I would also mention the fact that select does not seem to work with a struct field, perhaps that can be fixed too (even if it might be by design).
SUGGESTION:
I am not entirely happy of creating an alias variable to get around the issue of the built-in select function with struct fields. Since the implementation of select is rather trivial, as can be found in the docs, I would introduce a novel inline function to replace the built-in select function:
typedef Struct
{
int field;
}
inline my_select (var, lower, upper)
{
var = lower;
do
:: var < upper -> var++;
:: break;
od;
}
init
{
Struct st;
my_select(st.field, -1, 1);
printf("%d\n", st.field);
}
I would try to remove a specific character from a given string in the following code.
int main(void){
string query="a*de*da";
string org;
uint8_t rmc='*';
std::vector<string::const_iterator> wpos;
for(string::const_iterator itr = org.begin();
itr!=org.end();
++itr){
if(*itr==rmc){
wpos.push_back(itr);
}
}
uint64_t wcnt=0;
for(auto witr: wpos){
org.erase( witr-(wcnt++) );
}
query=org;
return 0;
}
In this code, I would expect that query="adeda" however, I got an error
error: no matching function for call to ‘std::basic_string<char>::erase(__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >)’
org.erase(witr-wcnt);
My experimental setting is g++ 4.9.2 of devtoolset-3 on CentOS6.7
From C++98 to C++11, the signature of std::string::erase changed from
iterator erase(iterator p)
to
iterator erase(const_iterator p)
It seems like g++4.9.2 still uses the old version. Your example should compile if you change string::const_iterator to string::iterator.
I'm trying to write a simple thread safe stack using c++11 atomic class.
These are what I've come so far.
void pushNode(Node* node) {
//
// node->_next = _head.load(std::memory_order_relaxed);
// while(!_head.compare_exchange_weak(node->_next, node));
//
// http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange
// Note: the above use is not thread-safe in at least
// GCC prior to 4.8.3 (bug 60272), clang prior to 2014-05-05 (bug 18899)
// MSVC prior to 2014-03-17 (bug 819819). The following is a workaround:
Node* head = _head.load(std::memory_order_relaxed);
do {
node->_next = head;
} while(!_head.compare_exchange_weak(head, node,
std::memory_order_release, std::memory_order_relaxed));
}
Node* popNode() {
Node* head;
Node* expected = _head.load(std::memory_order_relaxed);
do {
head = expected;
} while(head && !_head.compare_exchange_weak(expected, head->_next,
std::memory_order_release, std::memory_order_relaxed));
if(head)
head->_next = nullptr;
return head;
}
void pop() {
delete popNode();
}
private:
std::atomic<Node*> _head;
I also write a testcase to find out how solid this stack is under certain conditions (3 threads, each commits a million times of push and pop operations randomly). And the answer is not much.
The testcase crashes some time, raising an access violation exception reading 0xbaadf00d 0xfeeefeee 0xcdcdcdcd or some other invalid memory address.
After a few days googling, the only thing I've found could possibly cause this problem is Is std::atomic_compare_exchange_weak thread-unsafe by design. And as commented in the code, I find a workround here, std::atomic::compare_exchange_weak. Dont know whether the ms guy get rid of this buggy implementations in my compiler (MSVC 2015 community) or not, I just apply the workround patch.
But no magic appears, the testcase crashes as usual.
Is std::atomic::compare_exchange_weak still bugly implemented, or I just did something stupid?
For various (C++11 std::string-change-related) reasons I would like to use a non-std::string string class in some places in my C++11-ish code, which need to be agreeable with several versions of several C++ compilers.
Now, I don't really mind whether my strings behave in pre-C++11-style or post-C++11 way; and I don't care about performance either. I just want a nice reliable string class which under no circumstances gives me errors involving std::__cxx11::string and other such voodoo.
What are my options? Can I/should I replicate some single compiler's implementation in my own header files? Is GCC's vstring an option? Something else?
template<class T>
struct crappy_string {
mutable std::vector<T> buffer;
T const* c_str() const {
if (buffer.empty() || buffer.back())
buffer.push_back(0);
return buffer.data();
}
friend bool operator<( crappy_string const& lhs, crappy_string const& rhs ) {
lhs.c_str(); rhs.c_str(); // ensure null terminator in both
return lhs.buffer < rhs.buffer;
}
};
This satisfies the minimal requirements you gave in the comments.
I am new to module writing and need a circular buffer[1] and a vector. Since the Linux kernel apparently provides some data structures (lib) (list, trees), I was wondering if there is a vector equivalent?
While I think I am well capable to write my own, I prefer libraries for such things to prevent the duplication of code and to avoid errors.
[1] Found while composing the question, kfifo, also Queues in the Linux Kernel might be of interest.
As far as I know there is no implementation of vectors till 4.1 Linux kernel. And it does not make any sense to have one as vectors can be designed with the basic data structures whose implementation is already provided in Linux kernel.
I'm a bit late, but if anyone needs to implement a generalized vector in C, it can be done using void pointers and a sizeof operator on initialization. It would look something like this:
struct MyVec {
void *data;
size_t stored_sizeof;
size_t size;
size_t allocated_size
};
#define STARTING_ALLOCATED_SIZE 10
void MyVec_init(struct MyVec *self, size_t sizeof_data_type) {
self->stored_sizeof = sizeof_data_type;
self->data = malloc(self->stored_sizeof * STARTING_ALLOCATED_SIZE);
self->size = 0;
self->allocated_size = STARTING_ALLOCATED_SIZE;
}
void MyVec_deinit(struct MyVec *self) {
free(self->data);
}
bool MyVec_at(struct MyVec *self, size_t index, void *to_fill) {
if (index >= size)
return false;
memcpy(to_fill, self->data + (index * self->stored_sizeof), self->stored_sizeof);
return true;
}
and all the other methods that you might need, just being sure to use stored_sizeof whenever indexing, adding/removing elements, and the like.