Pascal pointer to pointer SyntaxError and Incompatible types - pascal

Since there's no way to create refereces (is there?) I have to do it with a pointer to another pointer. This gives me an error:
type
PNode = ^TNode;
TNode = record
char: char;
next: PNode;
children: PNode;
end;
PPNode = ^PNode;
var
current_node: PPNode;
function find_or_insert_peer(var node: PNode; character: char): PNode;
current_node := #find_or_insert_peer(current_node^, character)^.children;
x.pas(121,23) Error: Incompatible types: got "<address of function(var PNode;Char):^TNode;Register>" expected "PPNode"
x.pas(121,43) Fatal: Syntax error, ";" expected but "(" found
Fatal: Compilation aborted
I also tried this but it does not compile because of SyntaxError
current_node := #(find_or_insert_peer(current_node^, character)^.children);
Edit
Please help. I've even created a demo in c++ to show you this is legal. http://cpp.sh/8mxe

As mentioned in a witty-called article "Addressing pointers" linked in comments the # operator might not work properly with more complex expressions. Its equivalent addr() will do the trick.
current_node := addr(find_or_insert_peer(current_node^, character)^.children);

Related

invalid initialization of non-const reference of type ‘Node*&’ from an rvalue of type ‘std::atomic<Node*>::__pointer_type {aka Node*}’

I have the following snippet of code:
struct Node {
int data;
Node *next;
};
atomic<Node*> head;
atomic<Node*> temp1 = head.load();
..
Node *temp2 = new Node;
//initialise values
head.compare_exchange_strong(temp1, temp2);
However, I get the following error:
invalid initialization of non-const reference of type ‘Node*&’ from an rvalue of type ‘std::atomic::__pointer_type {aka Node*}’.
I am not getting which reference is constant here. Any help will be appreciated.
Simple answer is that temp1 should be a Node*, not an Atomic,
as cmp/xchg takes two simple type variables.
But I don't really understand what you are trying to achieve.
Surely if you want next to be protected against threading, then it should be declared Atomic inside the struct?

C++ iterator mismatch error

I am keeping track if instances of my class using std::vector to store pointers to all of the class objects. I'm wrapping things up and want to remove the pointer in the destructor... but I am getting the following error:
Brazos.cpp:15:89: error: cannot convert 'std::vector::iterator {aka __gnu_cxx::__normal_iterator >}' to 'const char*' for argument '1' to 'int remove(const char*)'
instanceAddress.erase(std::remove(instanceAddress.begin(), instanceAddress.end(), this) instanceAddress.end());
it seems I may need to dereference the iterator... Here is my code:
std::vector<Brazos*> Brazos::instanceAddress;
Brazos::Brazos(Mano mano)
{
instanceAddress.push_back(this);
_mano = mano;
}
Brazos::~Brazos(void)
{
instanceAddress.erase(std::remove(instanceAddress.begin(), instanceAddress.end(), this) instanceAddress.end());
}
You're missing a comma:
instanceAddress.erase(std::remove(instanceAddress.begin(), instanceAddress.end(), this), instanceAddress.end());
^
Also, the error message refers to int std::remove(const char*), so make sure you have #include <algorithm> for the correct std::remove.

passing argument 1 of 'strlen' makes pointer from integer without a cast

It is not clear why I get a warning of:
[Warning] passing argument 1 of 'strlen' makes pointer from integer without a cast [enabled by default]
expected 'const char *' but argument is of type 'char'
on two of the 3 statements containing strlen() below.
Even when I attempted to cast *str it still gave the same warning.
bfr is a character buffer. *str points to that char buffer after the call to
gets(). If I use strlen(*str) I get a warning. If I use strlen(bfr) I do not.
But *str should be the equivalent to bfr. Thus the confusion regarding the error.
Now in reality, strlen arg 1 is defined as strlen(const char *string). So I
would have expected strlen(bfr) to also produce an error since bfr[] is a
char string and not a const char either.
And where is the integer that is being made into a pointer?
I am using gcc under wXDev-C++.
void test(){
FILE *fileID = fopen("somefile.txt","r");
char *str, len;
char bfr[16];
str = fgets(bfr,16,fileID); // str will be set equal to &bfr[0]
len = strlen(*str); // This gives a warning
len = strlen((const char)*str); // This gives a warning
len = strlen(bfr); // This does not give a warning
}
Sometimes you just need to take a fresh look in the morning at a problem. I realized that strlen is looking for a pointer to a string and 'str' is defined as a pointer. So *str would be a pointer to a pointer. So the warning was correct. It should read len = strlen(s) not len = strlen(*s). And it is 'str' pointing to 'bfr' not *str;
Answered my own question.

Cannot iterate a flat map

I am working with a boost flat_map and trying to iterate through it, however, I cannot figure out how to create the iterator.
my_map = mySeg.find<tlsSHMMap>("temp_map").first; //fetch a pointer to the map
tlsShmemAllocator alloc_inst (mySeg.get_segment_manager());
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
row != my_map->end();
++row)
{
//do stuff
}
The 'tlsStorage' is a struct that I use to store data from a database. The boost flat map is declared as follows somewhere else in the code:
boost::container::flat_map tls_temp_map = mySeg.construct<tlsSHMMap>("temp_map") (std::less<int>() ,alloc_inst); //object name
The code that I have above does not work. Here are the errors, any ideas?
src/dbm/dbm_shm_server.cc: In member function 'int redcom::dbm::ShmServer::StartServer()':
src/dbm/dbm_shm_server.cc:353:24: warning: unused variable 'tls_main_map' [-Wunused-variable]
tlsSHMMap* tls_main_map;
^
src/dbm/dbm_shm_server.cc:354:24: warning: unused variable 'tls_temp_map' [-Wunused-variable]
tlsSHMMap* tls_temp_map;
^
src/dbm/dbm_shm_server.cc: In member function 'void redcom::dbm::ShmServer::fake_notify()':
src/dbm/dbm_shm_server.cc:2023:84: error: the value of 'alloc_inst' is not usable in a constant expression
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2021:40: note: 'alloc_inst' was not declared 'constexpr'
const tlsShmemAllocator alloc_inst (mySeg.get_segment_manager());
^
src/dbm/dbm_shm_server.cc:2023:95: error: type/value mismatch at argument 4 in template parameter list for 'template<class Key, class T, class Compare, class Allocator> class boost::container::flat_map'
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2023:95: error: expected a type, got 'alloc_inst'
src/dbm/dbm_shm_server.cc:2023:113: error: invalid type in declaration before 'row'
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2023:113: error: expected ';' before 'row'
src/dbm/dbm_shm_server.cc:2023:113: error: 'row' was not declared in this scope
src/dbm/dbm_shm_server.cc:2024:37: error: expected ')' before ';' token
row != my_map->end();
^
src/dbm/dbm_shm_server.cc:2023:98: warning: unused variable 'const_iterator' [-Wunused-variable]
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2025:19: error: 'row' was not declared in this scope
++row)
^
src/dbm/dbm_shm_server.cc:2025:22: error: expected ';' before ')' token
++row)
^
distcc[31606] ERROR: compile src/dbm/dbm_shm_server.cc on localhost failed
scons: *** [debug/build/x86_64-unknown-freebsd9.2/dbm/dbm_shm_server.o] Error 1
scons: building terminated because of errors.
Your code appears to be thoroughly confused. And the errors only slightly related to the code shown...[1]
Never mind, I have figured out that in your actual code (ShmServer::fake_notify) you are declaring allocInst, nearly like you showed, but const:
const tlsShmemAllocator alloc_inst (mySeg.get_segment_manager());
Which also handsomely explains why your loop control variable has an invalid type:
error: the value of 'alloc_inst' is not usable in a constant expression
error: expected a type, got 'alloc_inst'
I mean, really, the compiler couldn't be much more explicit about it. In case this wasn't clear enough it added pretty ascii art:
for(flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
So yeah... you're trying to pass an allocator as an allocator type argument? Instead, use types as template arguments. Note the use of typedefs to reduce code clutter:
typedef boost::container::flat_map<
int, tlsStorage, std::less<int>, tlsShmemAllocator> ShmTable;
typedef ShmTable::const_iterator ShmTableIt;
for(ShmTableIt rowit=my_map->begin(); rowit!=my_map->end(); ++rowit)
{
ShmTableIt::value_type const& row = *rowit;
int id = row.first;
tlsStorage const& rowData = row.second;
}
Now of course, with C++11 you could write that without all those typedefs
for(auto rowit=my_map->begin(); rowit!=my_map->end(); ++rowit)
{
int id = rowit->first;
auto& rowData = rowit->second;
}
Or even more to the point:
for(auto const& row : *my_map)
{
int id = row.first;
auto& rowData = row.second;
}
Try to reduce on cruft so you don't get overwhelmed by the code :)
[1] some points in case:
boost::container::flat_map is a template, so your declaration cannot possibly be correct. I suspect you actually have
tlsSHMMap* tls_temp_map;
Why would you give us false code? That's unrelated?
In fact, is it my_map in your actual code? or tls_temp_map? Or tls_main_map (which you don't show, but is declared and never used...)?

Type of iterator for range-based for loop

Say I have the following code:
std::vector<std::string> foo({"alice", "bob"});
for (const std::string &f : foo)
std::cout << f.size() << std::endl;
if I make a mistake and change f.size() to f->size(), I get the following error from GCC:
error: base operand of ‘->’ has non-pointer type ‘const string {aka
const std::basic_string}
Why is the actual type const std::basic_string<char> rather than const std::basic_string<char> & (reference)?
The left-hand side of -> operator is an expression. There ain't no such thing as an expression with a reference type:
5p5 If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.

Resources