This question already has answers here:
What is the C++ equivalent to C's designated initializers?
(4 answers)
Closed 7 years ago.
I'm trying to convert some code from C to C++
This is a project using a raspberry pi with camera module and I'd like to analyse pictures with it.
But on this piece of code (somebody else created) I get this error
231:8: error: expected primary-expression before ‘.’ token
Which is this line:
.max_stills_w = state->width,
I tried everything I could find but it keeps giving me other errors
video_port = camera->output[MMAL_CAMERA_VIDEO_PORT];
still_port = camera->output[MMAL_CAMERA_CAPTURE_PORT];
// set up the camera configuration
{
MMAL_PARAMETER_CAMERA_CONFIG_T cam_config =
{
{ MMAL_PARAMETER_CAMERA_CONFIG, sizeof(cam_config) },
.max_stills_w = state->width,
.max_stills_h = state->height,
.stills_yuv422 = 0,
.one_shot_stills = 0,
.max_preview_video_w = state->width,
.max_preview_video_h = state->height,
.num_preview_video_frames = 3,
.stills_capture_circular_buffer_height = 0,
.fast_preview_resume = 0,
.use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RESET_STC
};
mmal_port_parameter_set(camera->control, &cam_config.hdr);
}
// Set the encode format on the video port
C++ doesn't support named initializers, only positional ones.
You'll have to read the struct definition and arrange all the initializers into declaration order.
Any members which weren't being named in the C code were being initialized to zero implicitly. You may have to make some of them explicit in order to not skip positions.
If this code is from JVCleave then it appears that the members are already in the correct order, you can just comment out the names and it will still work.
The named structure member initialisation in C99 is not implemented in C++. In C++ you can perform member initialisation using a constructor. E.g:
struct sConfig
{
int m_x ;
int m_y ;
sConfig( int x, int y ) : m_x(x),
m_y(y)
{}
} ;
Or:
struct sConfig
{
int m_x ;
int m_y ;
sConfig( int x, int y )
{
m_x = x ;
m_y = y ;
}
} ;
or even a combination of the two methods. Then you instantiate an object thus:
sConfig myConfig( 10, 20 ) ;
Initialising m_x and m_y to 10 and 20 respectively in this example.
You can then of course only perform the initialisation provided by the structures defined constructors; but that is not necessarily a bad thing - letting the user arbitrarily decide which members to initialise is not particularly safe or maintainable. You can of course define multiple constructors to perform different initialisations; you would normally want define a default constructor for example:
struct sConfig
{
int m_x ;
int m_y ;
sConfig( int x, int y ) : m_x(x),
m_y(y)
{}
sConfig( ) : m_x(0),
m_y(0)
{}
} ;
So that in this example:
sConfig myConfig ;
is equivalent to all of the following:
sConfig myConfig( 0, 0 ) ;
sConfig myConfig = { 0, 0 } ;
sConfig myConfig = {0} ;
Related
TLDR: Is there a way make D's SumType play nice with opCmp while maintaining its functionality?
Context
I'm writing a program for which D's native SumType works almost completely. However, I would like to be able to do the following:
alias Foo = SumType!(int, string);
Foo x = 3;
Foo y = 5;
writeln(max(x, y));
However, since no ordering is natively defined for SumType, I receive the following error:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\comparison.d(1644): Error: static assert: "Invalid arguments: Cannot compare types SumType!(int, string) and SumType!(int, string) for ordering."
mwe.d(11): instantiated from here: `max!(SumType!(int, string), SumType!(int, string))`
I was able to remedy this specific issue using the following method:
import std.stdio : writeln;
import std.exception : assertThrown;
import std.algorithm.comparison : max;
import core.exception : AssertError;
import std.sumtype;
struct Foo {
SumType!(int, string) value;
this(T)(T v) {
value = v;
}
ref Atom opAssign(T)(T rhs) {
value = rhs;
return this;
}
int opCmp(Foo other) {
return match!(
(a, b) => a < b ? -1 : a == b ? 0 : 1,
(_1, _2) => assert(0, "Cannot match")
)(value, other.value);
}
}
void main() {
Foo x = 3;
Foo y = 7;
Foo z = "asdf";
assert(x < y); // comparing ints works correctly
assertThrown!AssertError(x < z); // cannot compare int and string
assert(max(x, y) == y); // D's max works
}
The Problem
While I can now use x.value.match!(...) where I used to use x.match!(...), I would like to still be able to call .match! directly on x, and also use match!(...)(x, y) instead of match!(...)(x.value, y.value). I do not like the idea of inserting hundreds of .value throughout my code just to make certain functions like max work, and would prefer if there were a more elegant solution. I tried tinkering around with defining a custom opDispatch using mixins but I couldn't get that to play nicely with the existing SumType:
struct Foo {
SumType!(int, string) value;
this(T)(T v) {
value = v;
}
ref Atom opAssign(T)(T rhs) {
value = rhs;
return this;
}
int opCmp(Foo other) {
return match!(
(a, b) => a < b ? -1 : a == b ? 0 : 1,
(_1, _2) => assert(0, "Cannot match")
)(value, other.value);
}
auto opDispatch(string name, T...)(T vals) {
return mixin("value." ~ name)(vals);
}
}
void main() {
Foo y = 7;
y.match!(
(int intValue) => writeln("Received an integer"),
(string strValue) => writeln("Received a string")
);
}
And I am unable to decode the error which results:
mwe.d(38): Error: none of the overloads of template `std.sumtype.match!(function (int intValue) #safe
{
writeln("Received an integer");
return ;
}
, function (string strValue) #safe
{
writeln("Received a string");
return ;
}
).match` are callable using argument types `!()(Foo)`
C:\D\dmd2\windows\bin\..\..\src\phobos\std\sumtype.d(1659): Candidate is: `match(SumTypes...)(auto ref SumTypes args)`
with `SumTypes = (Foo)`
must satisfy the following constraint:
` allSatisfy!(isSumType, SumTypes)`
Beyond that I am out of ideas as to how to find a less clunky solution.
I suggest giving alias this a try. Similar to class inheritance, this lets you specialize a type and let other things fall back to the original member.
import std.stdio : writeln;
import std.exception : assertThrown;
import std.algorithm.comparison : max;
import core.exception : AssertError;
import std.sumtype;
struct Foo {
SumType!(int, string) value;
this(T)(T v) {
value = v;
}
int opCmp(Foo other) {
return match!(
(a, b) => a < b ? -1 : a == b ? 0 : 1,
(_1, _2) => assert(0, "Cannot match")
)(value, other.value);
}
alias value this;
}
void main() {
Foo x = 3;
Foo y = 7;
Foo z = "asdf";
assert(x < y); // comparing ints works correctly
assertThrown!AssertError(x < z); // cannot compare int and string
assert(max(x, y) == y); // D's max works
// this will now automatically fall back to y.value.match
y.match!(
(int intValue) => writeln("Received an integer"),
(string strValue) => writeln("Received a string")
);
}
See, you still must construct your special type, but then after that, it will look up there for members. It will find the opCmp, letting it extend the type. But then for everything else, since it isn't there, it will try checking obj.value instead, falling back to the original type.
This doesn't always work, and it means it will implicitly convert too, meaning you can pass a Foo to a void thing(SumType!(int, string)) with it passing foo.value to the function, which may or may not be desirable.
But I think it is the closest thing to what you want here.
(note btw why you got an error originally is that match isn't actually a member of SumType. it is an outside free function that takes all the match lambdas as template arguments. An opDispatch could forward template arguments too - it can be done in a two-level definition - but since match is not a member anyway, it isn't quite going to solve things anyway whereas the alias this does seem to work)
This is sort of a design doubt .
Scenario: I have an array which contain some integer elements . This array is populated by 1 module (.so) in my code base say X. It is then shared to another module say Y (.so) . At run time X module identifies that module Y would need to work on few fields of the array and modify it and that was the reason X shared the array to Y . ( Both these so are consumed into one binary .)
Once Y returns the module X prints the array .
Problem : How can I enforce programatically that module Y does not modify any other array index other than the one identified by X . SInce the whole array is passed between modules i cant make it const as then Y would not be able to change any field . You can say i want to enforce const-ness for few fields identified at run time .
How about this:
template <class T> class CProtectedArray {
private:
T* m_aItems;
unsigned int* m_aMask;
public:
CProtectedArray(int cElem, bool fInitialProtect) : m_aItems(NULL) {
int cbElem = sizeof(T)*cElem;
int cbMask = sizeof(int)*(cElem+31)/32;
m_aItems = (T*)malloc(cbElem + cbMask);
m_aMask = (unsigned int*)(m_aItems + cElem);
memset(m_aItems, 0, cbElem);
memset(m_aMask, fInitialProtect ? -1 : 0, cbMask);
}
~CProtectedArray() {
if (m_aItems)
free(m_aItems);
}
bool IsProtected(int iItem) { return !!(m_aMask[iItem>>5] & (1<<(iItem&31))); }
void Protect(int iItem) { m_aMask[iItem>>5] |= 1<<(iItem&31); }
void UnProtect(int iItem) { m_aMask[iItem>>5] &= ~(1<<(iItem&31)); }
void Set(int iItem, T val) {
if (!IsProtected(iItem))
m_aItems[iItem] = val;
}
};
int main(int argc, char* argv[])
{
CProtectedArray<int> A(100, true);
bool f = A.IsProtected(30); // f = true
A.Set(30, 23); // nothing happens
A.UnProtect(30);
f = A.IsProtected(30); // f = false
A.Set(30, 24); // sets element 30 to 24
A.Protect(30);
f = A.IsProtected(30); // f = true
A.Set(30, 25); // nothing happens
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
How do I send Tcl array to C++? I have written the following code:
Tcl:
set ns [new Simulator]
set n [$ns node]
$n set X_ 100
$n set Y_ 30
$n set Z_ 0
set x [$n set X_]
set y [$n set Y_]
set z [$n set Z_]
#after 2000
set b {12 2 3 4 5}
set aa [new "Application/Trust/ITLeach"]
$aa set bufer_ 1
$aa set allnode_ $n
$aa set X_ $x
$aa set Y_ $y
$aa set Z_ $z
$aa set ClausterHeadID_ [array get b] **#send array to c++**
$ns at 0.0 "$aa start"
puts $b
$ns run
ITLEACH.h:
#ifndef ns_ITLeach_h
#define ns_ITLeach_h
#include "app.h"
#include "node.h"
#include "tcl.h"
#include "mobilenode.h"
#include <iostream>
#include <fstream>
class ITLeach;
#define TCL_OK 0
class ITLeach : public Application {
public:
ITLeach();
virtual int command(int argc, const char*const* argv);
protected:
// need to define recv and timeout
void start();
int Buffer;
MobileNode * node ;
ofstream nodeSetting;
double XPos ;
double YPos ;
double ZPos ;
int ClausterHeadID [] ; //int array that passed from tcl file
int ClausterID [] ;
int id_node;
};
#endif
ITLEACH.cc:
/*
* ITLeach.cc
*
* Created on: Oct 29, 2013
* Author: root
*/
#include "ITLeach.h"
static class ITLeachClass : public TclClass {
public:
ITLeachClass() : TclClass("Application/Trust/ITLeach") {}
TclObject* create(int, const char*const*) {
return (new ITLeach());
}
} class_app_ITLeach;
ITLeach::ITLeach() : Application() {
Tcl_Obj *baObj = Tcl_NewObj();
bind("bufer_",&Buffer);
bind("allnode_",&node);
bind("X_",&XPos);
bind("Y_",&YPos);
bind("Z_",&ZPos);
bind("ClausterHeadID_",(int *) &ClausterHeadID); // call array from tcl
bind("ClausterID_",ClausterID);
bind("id_",&id_node);
}
int ITLeach::command(int argc, const char*const* argv) {
if (strcmp(argv[1], "start") == 0) {
ITLeach::start();
return(TCL_OK);
}
return(ITLeach::command(argc, argv));
}
void ITLeach::start()
{
//double x=0, y =0 , z =0;
nodeSetting.open("./leachnode.txt",fstream::app);
//node = (MobileNode*)Node::get_node_by_address(i);
//node->location()->getLocation(x,y,z);
//node->getLoc(&x,&y,&z);
nodeSetting << "id " << id_node << " x "<< XPos << " y " << YPos << " z " << ZPos <<"\n";
nodeSetting.close();
printf(" claster head number : %d \n" ,ClausterHeadID[1]);
printf("node number is : %d \n",Buffer);
}
I send array from Tcl with this code:
$aa set ClausterHeadID_ [array get b] **#send array to c++**
and receive array from C++ with this code:
bind("ClausterHeadID_",(int *) &ClausterHeadID); // call array from tcl
But it doesn't work, please help me.
If you've got that command bound to the string interface (i.e., the arguments arrive via int argc, char **argv) then you use Tcl_SplitList() to take apart the relevant argument (which might be argv[argc-1], i.e., the last argument) and then Tcl_GetInt() to retrieve an integer from each of those values. Those integers are the members of that Tcl list.
int listc;
char **listv;
if (Tcl_SplitList(interp, argv[argc-1], &listc, &listv) != TCL_OK) {
// wasn't a valid list!
return TCL_ERROR;
}
std::vector<int> theArray(listc, 0);
for (int i=0 ; i<listc ; i++) {
if (Tcl_GetInt(interp, listv[i], &theArray[i]) != TCL_OK) {
// wasn't an int in the list!
return TCL_ERROR;
}
}
This isn't very fast! For a faster way, you need to use the Tcl_Obj-based API (the Tcl_Obj is the fundamental Tcl first-class value type), starting with registering your implementation function correctly. After that, it's fairly easy to convert the above code:
int listc;
Tcl_Obj **listv;
if (Tcl_ListObjGetElements(interp, argv[argc-1], &listc, &listv) != TCL_OK) {
// wasn't a valid list!
return TCL_ERROR;
}
std::vector<int> theArray(listc, 0);
for (int i=0 ; i<listc ; i++) {
if (Tcl_GetIntFromObj(interp, listv[i], &theArray[i]) != TCL_OK) {
// wasn't an int in the list!
return TCL_ERROR;
}
}
The big difference? A Tcl_Obj knows whether it is holding a string or an integer (or a float or any number of other things) and so the Tcl runtime doesn't normally need to reparse or type-convert values, whereas if everything is a string, you do a lot of conversions. (It's common to say “Everything is a string” in Tcl, but that's inaccurate; the correct version is “Everything has a perfect string serialization, or is a named entity” but that's rather more verbose.)
I have a class, in it is a private member variable called which is an int. For some reason, if I change its value in a method (on the constructor, for example), it will change just fine. But if I change it on a different method and use printf to output what its contents are on yet another different method, the value is not carried over and is changed into a very very large number.
Header:
class Fruit {
private:
int m_fruitState; // 0 = IDLE, 1 = GROWING, 2 = READY, 3 = FALLEN, 4 = ROTTEN
int m_fruitTimer;
public:
Fruit ( );
int getFruitState( ); // Returns m_fruitState
void setFruitState( int fState );
void growFruit( CCTime dt ); // Called every 1 second (CCTime is a cocos2d-x class)
};
CPP
#include "Fruit.h"
Fruit::Fruit( ) {
// Set other member variables
this -> setFruitState( 0 ); // m_fruitState = 0
this -> m_fruitTimer = 0;
this -> m_fruitSprite -> schedule( schedule_selector( Fruit::growFruit ), 1.0 ); // m_fruitSprite is a CCSprite (a cocos2d-x class). This basically calls growFruit() every 1 second
}
int getFruitState( ) {
return this -> m_fruitState;
}
void setFruitState( int state ) {
this -> m_fruitState = state;
}
void growFruit( CCTime dt ) {
this -> m_fruitTimer++;
printf( "%d seconds have elapsed.", m_fruitTimer );
printf( "STATE = %d", this -> m_fruitState ); // Says my m_fruitState is a very big number
// This if condition never becomes true, because at this point, m_fruitState = a very big number
if ( this -> getfruitState( ) == 0 ) { // I even changed this to m_fruitState == 0, still the same
if ( this -> m_fruitTimer == 5 ) { // check if 5 seconds have elapsed
this -> setFruitState( 1 );
this -> m_fruitTimer = 0;
}
}
}
And then on the main, I make an instance of MyClass.
I have no idea why that happens. Why does C++ do that and how do I fix it?
Thanks in advance.
The "selector" argument to schedule should be a SEL_SCHEDULE, where
typedef void(CCObject::* SEL_SCHEDULE)(float)
i.e it should be a member function of a CCObject.
It is also supposed to be a member of the object you call schedule on, otherwise the target when it's called will be wrong.
I suspect that this
this -> m_fruitSprite -> schedule( schedule_selector( Fruit::growFruit ), 1.0 );
causes a call to Fruit::growFruit with this pointing at the sprite, not the fruit, which leads to all kinds of unpleasantness.
(Note that schedule_selector does a C-style cast, which means that it's inherently unsafe. Don't use it.)
changeInt( int newInt ); // Assume newInt = 5
Remove the int from the above line.
void doSomething( ); {
Remove the ; from the above line.
Update: Now you're missing a ; from the end of the header file. Fixing all the obvious bugs (that would likely keep it from even compiling), it works fine for me. Either there's still a difference between the code you pasted and the real code, or you've found a compiler bug.
Constructor: myInt = 0
changeInt( int ) : myInt = 5
After constructor and calling changeInt(), myInt = 5
Alternative 1, reusing a temporary variable:
Sticker sticker;
sticker.x = x + foreground.x;
sticker.y = foreground.y;
sticker.width = foreground.width;
sticker.height = foreground.height;
board.push_back(sticker);
sticker.x = x + outline.x;
sticker.y = outline.y;
sticker.width = outline.width;
sticker.height = outline.height;
board.push_back(sticker);
Alternative 2, scoping the temporary variable:
{
Sticker sticker;
sticker.x = x + foreground.x;
sticker.y = foreground.y;
sticker.width = foreground.width;
sticker.height = foreground.height;
board.push_back(sticker);
}
{
Sticker sticker;
sticker.x = x + outline.x;
sticker.y = outline.y;
sticker.width = outline.width;
sticker.height = outline.height;
board.push_back(sticker);
}
Alternative 3, writing straight to the vector memory:
{
board.push_back(Sticker());
Sticker &sticker = board.back();
sticker.x = x + foreground.x;
sticker.y = foreground.y;
sticker.width = foreground.width;
sticker.height = foreground.height;
}
{
board.push_back(Sticker());
Sticker &sticker = board.back();
sticker.x = x + outline.x;
sticker.y = outline.y;
sticker.width = outline.width;
sticker.height = outline.height;
}
Which approach do you prefer?
Edit: For the sake of this discussion, assume that the assignments have to be made one by one outside of a constructor
My option - give Sticker a constructor that takes the parameters. then:
board.push_back( Sticker( outline.x, foo.bar, etc. ) );
Edit: Code to illustrate constructor parameter names:
#include <iostream>
using namespace std;
struct S {
int a, b;
S( int a, int b ) : a(a), b(b) {
}
};
int main() {
S s( 1, 2);
cout << s.a << " " << s.b << endl;
}
board.resize(sticker_count);
Then iterate through all the vector and set parameters.
Alternative 1. Why create a scope just for a variable? There is usually an enclosing scope nearby (at the minimum, you should keep your functions/procedures small so that will scope it).
Why? You can create a shorter variable name e.g. st in this case. Since the assignment will be nearby there should be no loss in clarity. Actually it will look simpler and cleaner.
Also, if the vector needs to be dereferenced/accessed from several other levels of indirection, then it will also simplify the code.
How about winforms style:
// Class members
Sticker sticker1;
Sticker sticker2;
Board board;
// Initialization
void InitBoard()
{
sticker1.x = x + foreground.x;
sticker1.y = foreground.y;
sticker1.width = foreground.width;
sticker1.height = foreground.height;
sticker2.x = x + outline.x;
sticker2.y = outline.y;
sticker2.width = outline.width;
sticker2.height = outline.height;
// Add to board
board.push_back(sticker1);
board.push_back(sticker2);
}