D Function literals cannot be class members - struct

While playing around with D's mixins, I came across this conundrum.
////////////////////////////////////////////////////////
// Proxy
////////////////////////////////////////////////////////
//What I'm aiming for
/*
struct Proxy4(T) if (isNumeric!T)
{
T* x;
T* y;
T* z;
T* w;
}
*/
//Preferred implementation
struct Proxy(T, uint n) if (2<=n && n<=4 &&
isNumeric!T)
{
//Declare pointer fields
mixin(iota(n).map!(i => ("T* "~"xyzw"[i]~";")).join());
}
This fails to compile since
function literals cannot be class members
This is hopefully quite simple to solve for someone out there.
Note:
I have tried debugging using writeln().
writeln(iota(4).map!(i => ("T* "~"xyzw"[i]~";")).join());
The above code prints:
T* x;T* y;T* z;T* w;
Edit:
My own answer was inferior to the answer of Peter Alexander, so I edited it out.

Actually, the problem seems to be the presence of a lambda function inside the mixin expression within your class/struct.
This works:
mixin( iota(n).map!(q{"T " ~ "xyzw"[a] ~ ";"}).join() );
Your original expression also works just fine outside of a class (for example, to declare local variables inside main()). There is no problem trying to run your code at compile time, it's just an odd DMD front-end implementation limitation.
There is a bug filed for this issue already.

Related

code within statically linked library src files returning null

This is for windows using MSVC compiler version 14.28.29910:
Libraries built using colcon. This was meant for a ROS2 application but I dont believe ROS has anything to do with it.
I have been stuck on this issue for two days now and I still am at a loss as to what is going on. Any help will be greatly appreciated.
I have a library that I am statically linking against. Library A. it is built with colcon. Could this be a linking issue or an issue with the fact that I build library A with a certain set of preprocessors and I build library B with a different set of preprocessors that change the Gameobject class to a different version shown below but same function implementations.
ament_auto_add_library(A STATIC
${SOURCES}
${HEADERS}
)
ament_target_dependencies(A ${ALL_DEPENDS})
install(TARGETS
A
EXPORT A_export
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
ament_export_libraries(A_export HAS_LIBRARY_TARGET)
I then link to it from a ros2 package using the standard
target_link_libraries(B A)
I have a object called Gameobject that is defined in library A.
#file --------------------------Gameobject.h
#ifdef InLibraryA
class Gameobject
{
int GetPosx(){return data.x;}
}
#else
class Gameobject
{
int GetPosx(){return data.x;}
}
#endif
#file --------------------------MoveGameObject.h
class MoveGameObject
{
int MoveGObj_inline(Gameobject* g)
{
return g->getPosx();
}
int MoveGObj(Gameobject* g);
}
#file --------------------------MoveGameObject.cpp
int MoveGameObject::MoveGObj(Gameobject* g)
{
return g->getPosx();
}
Now in library B , I do this within a subscription callback
SomeCallback()
{
Gameobject* g = GetGObjectFromPool();
MoveGameObject* m= new MoveGameObject();
//this will return NULL value
int posx = m->MoveGObj(g);
//this will be fine because it was inlined?
int possx = m->MoveGObj_inline(g);
}
You will see that I get null when calling the function that was NOT inlined for calling the getter function from Gameobject. I dont get null for the inlined function even though they run the exact same code. Note that this only happens to non-inline functions that call Gameobject functions. Does not happen to functions that do not read memory from Gameobject. addingTwoInts() for example works fine Non-inline. There are no errors. It is undefined behavior. Any ideas on what I could be doing wrong for this to happen? The simplified code above is the same as to what is happening in my code, just removed unnecessary details.

Visual C++ lambdas always output debug information

If I instantiate a lambda somewhere (and the compiler doesn't inline it), I can find a string showing where the lambda is located in my c++ code like this:
... ?AV<lambda_1>#?0??MyFunction#MyScopedClass#MyNamespace##SAXXZ# ...
I don't want this information in the executable, as it could give away important names of classes and functions.
All kinds of output debug information are turned off. If I use a normal function instead, the final executable doesn't have this information, so manually converting all lambdas into normal functions would "fix it". But what's the best way to handle this? Can we tell the compiler to transform lambdas into normal functions?
UPDATE: I tested with other compilers: g++ and clang. They both leave the same references. I also found another unanswered question about this Gcc - why are lambdas not stripped during release build Please don't come with the "why do you care about a few symbols anyway".
Here's some code you can test with:
#include <iostream>
#include <functional>
class MyUnscopedClass
{
public:
MyUnscopedClass(const std::function<void(int x)>& f) :
f(f)
{
}
std::function<void(int x)> f;
};
namespace MyNamespace
{
class MyScopedClass
{
public:
static void temp1(int x)
{
std::cout << x * (x + 1);
}
static void MyFunction()
{
//MyUnscopedClass obj(temp1); // no symbols
MyUnscopedClass obj([](int x) // ?AV<lambda_1>#?0??MyFunction#MyScopedClass#MyNamespace##SAXXZ#
{
std::cout << x;
});
obj.f(23);
}
};
}
int main()
{
MyNamespace::MyScopedClass::MyFunction();
}
With the help of #dxiv in the comments, I found the problematic setting.
Configuration Properties > General > C++ Language Standard
can't be, for some reason,
Preview - Features from the Latest C++ Working Draft (std:c++latest)
So I set it to the second most recent one
ISO C++17 Standard (std:c++17)
and I get a random identifier instead.
AV<lambda_f65614ace4683bbc78b79ad57f781b7f>##
I'm still curious how this identifier is chosen though.

"this" argument in boost bind

I am writing multi-threaded server that handles async read from many tcp sockets. Here is the section of code that bothers me.
void data_recv (void) {
socket.async_read_some (
boost::asio::buffer(rawDataW, size_t(648*2)),
boost::bind ( &RPC::on_data_recv, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
} // RPC::data_recvW
void on_data_recv (boost::system::error_code ec, std::size_t bytesRx) {
if ( rawDataW[bytesRx-1] == ENDMARKER { // <-- this code is fine
process_and_write_rawdata_to_file
}
else {
read_socket_until_endmarker // <-- HELP REQUIRED!!
process_and_write_rawadata_to_file
}
}
Nearly always the async_read_some reads in data including the endmarker, so it works fine. Rarely, the endmarker's arrival is delayed in the stream and that's when my program fails. I think it fails because I have not understood how boost bind works.
My first question:
I am confused with this boost totorial example , in which "this" does not appear in the handler declaration. ( Please see code of start_accept() in the example.) How does this work? Does compiler ignore the "this" ?
my second question:
In the on_data_recv() method, how do I read data from the same socket that was read in the on_data() method? In other words, how do I pass the socket as argument from calling method to the handler? when the handler is executed in another thread? Any help in form of a few lines of code that can fit into my "read_socket_until_endmarker" will be appreciated.
My first question: I am confused with this boost totorial example , in which "this" does not appear in the handler declaration. ( Please see code of start_accept() in the example.) How does this work? Does compiler ignore the "this" ?
In the example (and I'm assuming this holds for your functions as well) the start_accept() is a member function. The bind function is conveniently designed such that when you use & in front of its first argument, it interprets it as a member function that is applied to its second argument.
So while a code like this:
void foo(int x) { ... }
bind(foo, 3)();
Is equivalent to just calling foo(3)
Code like this:
struct Bar { void foo(int x); }
Bar bar;
bind(&foo, &bar, 3)(); // <--- notice the & before foo
Would be equivalent to calling bar.foo(3).
And thus as per your example
boost::bind ( &RPC::on_data_recv, this, // <--- notice & again
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
When this object is invoked inside Asio it shall be equivalent to calling this->on_data_recv(error, size). Checkout this link for more info.
For the second part, it is not clear to me how you're working with multiple threads, do you run io_service.run() from more than one thread (possible but I think is beyond your experience level)? It might be the case that you're confusing async IO with multithreading. I'm gonna assume that is the case and if you correct me I'll change my answer.
The usual and preferred starting point is to have just one thread running the io_service.run() function. Don't worry, this will allow you to handle many sockets asynchronously.
If that is the case, your two functions could easily be modified as such:
void data_recv (size_t startPos = 0) {
socket.async_read_some (
boost::asio::buffer(rawDataW, size_t(648*2)) + startPos,
boost::bind ( &RPC::on_data_recv, this,
startPos,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
} // RPC::data_recvW
void on_data_recv (size_t startPos,
boost::system::error_code ec,
std::size_t bytesRx) {
// TODO: Check ec
if (rawDataW[startPos + bytesRx-1] == ENDMARKER) {
process_and_write_rawdata_to_file
}
else {
// TODO: Error if startPos + bytesRx == 648*2
data_recv(startPos + bytesRx);
}
}
Notice though that the above code still has problems, the main one being that if the other side sent two messages quickly one after another, we could receive (in one async_read_some call) the full first message + part of the second message, and thus missing the ENDMARKER from the first one. Thus it is not enough to only test whether the last received byte is == to the ENDMARKER.
I could go on and modify this function further (I think you might get the idea on how), but you'd be better off using async_read_until which is meant exactly for this purpose.

Struct declaration order

If I define structs at the module level, I can reference not-yet defined structs.
struct S {
ComesLater c;
}
struct ComesLater {}
But If I do the same inside an unittest or a function block, it doesn't work:
unittest {
struct S {
ComesLater c;
}
struct ComesLater {}
}
Error: undefined identifier 'ComesLater'
Why is that? How can I get order-independent declarations inside functions? Is there some kind of forward-declaration in d? I need this because I generate structs using mixin and ordering the declarations in the order of their inner-dependencies would be quite some effort, sometimes impossible, if there are circularly referencing structs. (using pointers.)
Declarations inside functions, unittests, or anywhere else that statements can actually be executed are indeed order-dependent because their values may depend on the code before them running. Think of a local variable:
int a;
writeln(a);
a = b;
int b = get_user_line();
If order wasn't important there, when would the two functions get called? Would the user be asked for a line before the writeln as the declarations are rewritten?
The current behavior of making b an undefined variable error keeps it simple and straightforward.
It works independent of order in other contexts because there is no executable code that it can depend on, so there's no behavior that can change if the compiler needs to internally think about it differently.
So:
How can I get order-independent declarations inside functions?
Change the context such that there is no executable code... put it all inside another struct!
void main() { // or unittest { }
struct Holder {
static struct S {
C c;
}
static struct C {}
}
}
Since execution happens around the holder and doesn't happen inside it, the order of declaration inside doesn't matter again. Since you can define almost anything inside a struct, you can use this for variables, functions, other structs, and so on. Basically all you have to do is wrap your existing code inside the struct Holder {} brackets.
By making everything static inside, you can just use it like a container and reference the stuff with Holder.S, etc., on the outside.

inserting "this" into an STL map from the constructor

VERSION 1
class Doh {
private:
static std::map<const std::string, const Doh*> someMap;
std::string stringValue_;
public:
Doh(std::string str) : stringValue_(str) {
Doh::someMap.insert(
std::make_pair<const std::string,const Doh*>
(this->stringValue_,this)
);
}
}
The above was ok with MSVC 2010 but with MSVC 2008 it fails – and I guess it is because the object is not constructed yet when it is inserted in the map (I got a memory access violation).
So, I tried a delayed insertion, which worked:
VERSION 2
Doh(std::string str) : stringValue_(str) {
boost::thread(&Doh::insertIntoTheStaticMap,this);
}
void insertIntoTheStaticMap() {
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
Doh::someMap.insert(
std::make_pair<const std::string,const Doh*>
(this->stringValue_,this)
);
}
But as you might be able to guess, my intention is to have the static Doh::someMap as a common lookup dictionary.
VERSION 1 didn’t need any thread-safety because I would create all Doh instances in the same thread – in initialization blocks - which would be called by dynamic initializers before I enter main().
But with VERSION 2, the naïve sleep() is neither graceful nor reliable (not to mention, I might need to lock the map before insertion).
What would be a nice KISS approach?
Only potential issue I see is the initialization of the static member, if there are multiple source files. Try guarding it with a function.
class Doh {
private:
static std::map< std::string, Doh * > &get_map() {
static std::map< std::string, Doh * > someMap;
return someMap; // initialize upon first use
}
std::string stringValue_;
public:
Doh(std::string str) : stringValue_(str) {
get_map().insert(
std::make_pair
(this->stringValue_,this)
);
}
};
In neither version is there any sign of init for stringvalue_ - what does the debugger show you about this key when you hit the map insert in version 1 of the code? How is this field set up, and what is its type?
Running this in the debugger for VS2008 should allow you to narrow down the point of failure into the <map> source, I would have thought.

Resources