I have a lot of legacy code using macro of the form:
#define FXX(x) pField->GetValue(x)
The macro forces variable pField be in the scope:
.....
FIELD *pField = ....
.....
int i = FXX(3);
int j = FXX(5);
Is there way to replace the macro, without touching user code?
Since FXX(x) has a function invocation style, I thought about inline function or something similar.
UPD:
People just used to the macro, and I want to remain it as is.
How about using a find & replace function in your favorite editor...I think it would work fine in the example you gave in your question. Replace FXX with pField->GetValue and then remove the #define line
What is pField (besides a fine example of the abomination that is Systems Hungarian)? If, by chance, it's a global variable or a singleton or something that we only need one of, we could do a nifty trick like this:
int FFX(int x)
{
static FIELD *pField = ...; // remove this line if pField is global
return pField->GetValue(x);
}
Change the int types to whatever types you need it to operate on, or even a template if you need it to support multiple types.
Another alternative, suggested by #epatel, is to use your favorite text editor's find-and-replace and just change all the FFX(x) lines to pField->GetValue(x), thus eliminating the macro invokation in your code. If you want to keep a function invokation, you culd change FFX(x) to FFX(pField, x) and change the macro to take two arguments (or change it to a function that takes two arguments). But you might as well just take out the macro at that point.
A third alternative, is not to fix that which is not broken. The macro isn't particularly nice, but you may introduce greater problems by trying to remove it. Macros aren't the spawn of Satan (though this one has at least a few relatives in hell).
What you need is a function that relies on a variable being defined. The only way to do that is to declare that variable in the same scope as the function. But then your function would use that one instead of the one declared from where your function is called.
So I'm fairly confident it can't be done.
Well, if you can put this function definition where pField is already in scope:
int FXX(int x) { return pField->GetValue(x); }
Otherwise, there's no way to get pField into the the function without affecting existing code.
This may be a case where using the macro is the best alternative. Macros may be evil, but they are sometimes necessary. See http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15
I would leave it as it is, but just for the sake of discussion, and depending on what parts of the code are 'untouchable' you could define a functor that takes a pField and initialize after the variable is created in the same scope:
class FFX_t {
FFX_t( FIELD * pField ) : field_(pField) {}
int operator()( int index ) {
return field_->GetValue( index );
}
private:
FIELD *field_;
};
// usage:
void f() {
FIELD * pField = //...
FFX_t FFX(pField); // added after pField construction
// ...
int a = FFX(5);
}
But I insist in that changing working code for the sake of it when it will not really add any value is useless.
Related
I'm using the Qt framework to create a ui for my business logic.
The class responsible for building the ui provides several methods which, step by step, initialize the ui elements, layout them, group them and, finally, format (i.e. void MyUi::init3_formatUiElements()) them.
Naturally, some ui elements need numerous layout settings set, so this method might look like
void MyUi::init3_formatUiElements() {
_spinBox_distance->setMinimum(0.0);
_spinBox_distance->setMaximum(10.0);
_spinBox_distance->setSingleStep(0.5);
_spinBox_distance->setSuffix(" meters");
//...
//same for other widgets
return;
}
Objects like QDoubleSpinBox* _spinBox_distance are member fields of the MyUi class.
I would like to have a "temporary alias" for _spinBox_distance, in that the above method body simplifies to
void MyUi::init3_formatUiElements() {
//create alias x for _spinBox_distance here
x->setMinimum(0.0);
x->setMaximum(10.0);
x->setSingleStep(0.5);
x->setSuffix(" meters");
//...
//free alias x here
//same for other widgets: create alias x for next widget
//...
//free alias x here
return;
}
This would speed up the typing process and would make code fragments more copy/paste-able, especially for ui elements of a similar type.
Apart from scoping each block in curly braces
{ QDoubleSpinBox*& x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ QLabel*& x = _label_someOtherWidget;
//...
}
is there an elegant way to achieve this?
I tried the above syntax without scoping, but destructing x then of course leads to destruction of the underlying widget.
Maybe
QDoubleSpinBox** x = new QDoubleSpinBox*;
x = &_spinBox_distance;
(*x)->setMinimum(0.0);
//...
delete x;
but that doesn't make things much more type-easy (three extra lines, pointers to pointers, (*x))... :D
EDIT: This one does not work as after delete x, can't be redeclared another type.
What about using a macro ?
#define Set(argument) _spinBox_distance->set##argument
and
Set(Minimum(0.0));
Set(Maximum(10.0));
Set(SingleStep(0.5));
Set(Suffix(" meters"));
Or
#define Set(Argument, Value) _spinBox_distance->set##argument(Value)
Set(Minimum, 0.0);
Set(Maximum, 10.0);
Set(SingleStep, 0.5);
Set(Suffix, " meters");
Collecting the fundamental conceptual thoughts about the problem in question from the comments section, I may post the syntactical/technical answer to the question. This approach, without a doubt, should not be chosen in any kind of "complex" situation (or rather not at all).
bad coding style:
same name for different things
name which doesn't tell you anything about the object
move repeated code to dedicated functions, which...
may specialize on several ui types
are template functions
...
in case of Qt: Use Qt Designer.
...
{ auto x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ auto x = _label_someOtherWidget;
//...
}
will do the trick.
I think your code looks fine as it is, I find it much more useful to have the code be easy to read/understand than it is to have the code be easy to write. Remember that you write the code once, then have to read it many times afterwards.
In cases like this I make it easier to write with good old (and oft blamed for mistakes) copy and paste. Grab _spinBox_distance->set and just paste, finish the line, paste, finish the line, etc...
If, however, you find yourself writing those 4 setters in a row over and over again, then put them in 1 function that takes in the 4 parameters.
void SetParameters(QDoubleSpinBox* spinBox_distance, double min, double max, double step, std::string suffix)
{
//the setters
}
Consider the pair of functions below:
double MYAPI foo(double x) {
return x;
}
Register register_foo_([] {
return reg(&foo, "foo", ...); // function name repeated used
});
register_foo_ is a global variable, initialized before dllmain, whose constructor takes a lambda that repeatedly references the name of the function above it literally. It would be great if the registration code can move inside the function above to reduce the chance of making an error. I tried:
double MYAPI foo(double x) {
static Register register_foo_([] {
return reg(&foo, "foo", ...); // static local does not initialize before dllmain
});
return x;
}
If the above code works, then I can easily turn it into a macro that makes use of __FUNCNAME__. Is there a way to force the initialization of static local variable register_foo_ before dllmain?
Static variables local to a function (method) are initialized on first use of the function they're in. (They're zero-initialized at program load, then initialized "properly" via code when the function is first entered.) See the answers to this question. So your proposed movement of that code into the function changes the semantics of initialization, and it won't work.
Your original code worked, so what you apparently wanted was to move the code inside the function so it was somehow tied closer together in your mind - or the mind of a reader of the code - so that you could see that your string constant name and function name were right. Also maybe so that you could ensure the registration was done. And therefore what you want is to accomplish DRY.
The traditional (and only) way to accomplish that is by using a preprocessor macro that expands into the registration call and the function header.
You proposed using a macro yourself - now expand the macro so it not only generates the registration function but also the function header.
I suppose you want to achieve a syntax similar to:
DEFINE_FUNC(void, foo, (double x)) {
return x;
}
... and have the boilerplate autogenerated. That's actually very simple to do if you bring the Register above the function, with the help of a declaration:
#define DEFINE_FUNC(Ret, name, args) \
Ret name args; \
Register register_##name##_([] { \
return reg(&name, #name, ...); \
}); \
Ret name args
No, there's not. That's your answer.
I saw someone writing code like this , in a C++ class:
int foo ( int dummy )
{
this->dummy = dummy;
}
Shall we use code like that , will it cause problems ?
I tried to compile something like this , it seems to be worked.
#update:
I posted this mostly about the name dummy , and the internal variable this->dummy , and if it's problem causing
That's perfectly fine for a member function, other than you're missing a return statement. dummy will shadow the member variable and so you use this-> to refer to member.
int foo ( int dummy )
{
this->dummy = dummy; // set member to argument
return this->dummy;
}
Don't do this for things more complex than a simple set function, as it's confusing.
int foo ( int dummy ) // Bad practise! Rename this param as the function isn't a setter
{
this->dummy = dummy * 2 + 1;
return this->dummy;
}
There is nothing wrong with doing that perse. It can get confusing though if you use dummy assuming it is coming from the class but its actually coming from the parameter.
IMO, its better to use something to denote it is a class member. Some people use simply mDummy, other m_Dummy, others just write dummy_.
Its up to you what you prefer but most of all you should be consistent.
The code is not fine. The function is defined as returning an int but there is no return statement. The compiler might only give a warning about this, but the function calling foo might expect it to return a valid value, which it doesn't, and bad stuff might happen.
You have to do it this way if you're passing a parameter with the same name as the member variable.
But it might be a better practice to avoid a hidden (member-)variable by using different names. There's different coding styles, some would use dummy_, some would use mDummy or other ways to name member variables. This makes your code less confusing.
Well there is nothing wrong with your use, but the code needs to return an int as its an int function :)
Dummy variable in your current class is assigned to the passed int, however do remember they are different but now pointing to the same thing, therefore its better to give it a different name as its in a different.
You could however loose precision under certain variable types.
#include <stddef.h>
typedef struct intlist {
int size;
int i[1];
} intlist;
intlist *
makeintlist (int size)
{
intlist *ilp = malloc (offsetof (intlist, i[size])); /* not C++ */
ilp->size = size;
return ilp;
}
member variable size is allocated to size
That will work.
Don't do it, it's confusing!
I have a super class like this:
class Parent
{
public:
virtual void Function(int param);
};
void Parent::Function(int param)
{
std::cout << param << std::endl;
}
..and a sub-class like this:
class Child : public Parent
{
public:
void Function(int param);
};
void Child::Function(int param)
{
;//Do nothing
}
When I compile the sub-class .cpp file, I get this error
warning C4100: 'param' : unreferenced formal parameter
As a practice, we used to treat warnings as errors. How to avoid the above warning?
Thanks.
In C++ you don't have to give a parameter that you aren't using a name so you can just do this:
void Child::Function(int)
{
//Do nothing
}
You may wish to keep the parameter name in the declaration in the header file by way of documentation, though. The empty statement (;) is also unnecessary.
I prefer using a macro, as it tells not only the compiler my intention, but other maintainers of the code, and it's searchable later on.
The method of commenting out the argument name can easily be missed by people unfamiliar with the code (or me 6 months later).
However, it's a style-issue, neither method is "better" or more optimal with regards to code generated, performance or robustness. To me, the deciding factor is informing others of my intent through a standardized system. Omitting the parameter name and putting in a comment would work equally well:
void CFooBar::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
UNREFERENCED_PARAMETER(pNMHDR);
Alternatively:
void CFooBar::OnLvnItemchanged(NMHDR* /* pNMHDR */, LRESULT *pResult)
{
// Not using: pNMHDR
I would say that the worst solution is suppressing the warning message; that that will affect your entire file or project, and you'll lose the knowledge that maybe you've missed something. At least by adding the macro, or commenting out the argument name, you've told others that you've made a conscious decision to not use this argument and that it's not a mistake.
The Windows SDK in WinNT.h defines UNREFERENCED_PARAMETER() along with DBG_UNREFERENCED_PARAMETER() and DBG_UNREFERENCED_LOCAL_VARIABLE(). They all evaluate to the same thing, but the difference is that DBG_UNREFERENCED_PARAMETER() is used when you are starting out and expect to use the parameter when the code is more complete. When you are sure you'll never use the parameter, use the UNREFERENCED_PARAMETER() version.
The Microsoft Foundation Classes (MFC) have a similar convention, with the shorter UNUSED() and UNUSED_ALWAYS() macros.
Pick a style and stick with it. That way later on you can search for "DBG_UNREFERENCED_PARAMETER" in your code and find any instances of where you expected to use a argument, but didn't. By adopting a consistent style, and habitually using it, you'll make it easier for other and yourself later on.
Another technique that you can use if you want to keep the parameter name is to cast to void:
void Child::Function(int param)
{
(void)param; //Do nothing
}
As #Charles Bailey mentioned, you can skip the parameter name.
However, in certain scenarios, you need the parameter name, since in debug builds you are calling an ASSERT() on it, but on retail builds it's a nop. For those scenarios there's a handy macros (at least in VC++ :-)) UNREFERENCED_PARAMETER(), which is defined like this:
#define UNREFERENCED_PARAMETER(x) x
Note that the simple cast #R Samuel Klatchko posted also works, but I personally find it more readable if the code is explicit that this is an unreferenced parameter vs. simple unexplained cast like that.
Pragma works nicely too since it's clear you are using VS. This warning has a very high noise to benefit ratio, given that unreferenced parameters are very common in callback interfaces and derived methods. Even teams within Microsoft Windows who use W4 have become tired of its pointlessness (would be more suitable for /Wall) and simply added to their project:
#pragma warning(disable: 4100)
If you want to alleviate the warning for just a block of code, surround it with:
#pragma warning(push)
#pragma warning(disable: 4100)
void SomeCallbackOrOverride(int x, float y) { }
#pragma warning(pop)
The practice of leaving out the parameter name has the downside in the debugger that you can't easily inspect by name nor add it to the watch (becomes confused if you have more than one unreferenced parameter), and while a particular implementation of a method may not use the parameter, knowing its value can help you figure out which stage of a process you are in, especially when you do not have the whole call stack above you.
Since C++17 you also can use [[maybe_unused]] to avoid such warnings:
class Parent
{
public:
virtual void Function([[maybe_unused]] int param);
};
I would use a macro to suppress the unreferenced formal parameter warning:
#define UNUSED( x ) ( &reinterpret_cast< const int& >( x ) )
This has the following advantages:
Unlike #define UNUSED( x ) ( void )x, it doesn't introduce a need for the full definition of the parameter's type to be seen where no such need may have existed before.
Unlike #define UNUSED( x ) &x, it can be used safely with parameters whose types overload the unary & operator.
What about just adding reference with a comment:
void Child::Function(int param)
{
param; //silence unreferenced warning
}
This was also suggested here: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4100?view=vs-2019
I am trying to create a macro that takes a scope as a parameter.
I know, it is probably not a good thing etc etc.
I was trying this and got the problem that preprocessor looks for commas and parentheses... the problem is with enum.
How would I declare a enum inside a scope that is a parameter of a macro?
when the compiler see the comma between enum itens, it takes it as a separator.
If you are curious to know why I entered into this, is because I need to register my namespaces and classes, for namespaces I need to know when they are closed, so I was thinking to create a macro that initially calls a static function that register the namespace, encapsulate its contents and finally call a static function that removes the namespace from the registry.
With a macro it would be easier for the coder to do this and make sure he doesn't forget to remove the namespace in the end of the bracket.
Thanks,
Joe
EDIT:
I want a macro that accepts a scope as parameters:
#define MYMACRO(unkownscope) unknownscope
class MYMACRO({
// please, don't take this code seriously, it is just an example so you can understand my question
});
now, if I try:
#define MYMACRO(unkownscope) unknownscope
class MYMACRO({
enum {
anything = 1,
everything = 2
};
});
it won't compile because of the comma inside the enum, because the compiler thinks it is a separator of the macro. It doesn't happen with commas inside parentheses, example:
int a(){
int x = anyfunction(1, 2);
}
would compile normally because the comma is inside a double parentheses.
Sorry for not being able to explain earlier... my english is not that good and the words just keep skipping me =[
Ty for the answers!
Joe
It sounds like you are pushing the preprocessor beyond where it's willing to go. While it's not as elegant, how about breaking your macro in two (one pre- and one post-) and rather then passing a "scope" as parameter, you surround your scope with you pre- and post- macros.
So, if your macro looks something like:
SOMACRO({ ... });
You would instead do something like:
PRESOMACRO();
{ ... };
POSTSOMACRO();
#define SCOPED_STUFF(pre,post) pre; STUFF; post;
#define STUFF enum {a,b,c}
SCOPED_STUFF(a,b)
#undef STUFF
#define STUFF enum {q,r}
SCOPED_STUFF(c,d)
#undef STUFF
You are attempting to replicate RAII with a macro.
#define SCOPE(ns) NamespaceRegistrar _ns_rar(ns);
struct NamespaceRegistrar {
std::string _ns;
NamespaceRegistrar(const std::string& ns) : _ns(ns) { AcquireResource(_ns); }
~NamespaceRegistrar() { ReleaseResource(_ns); }
};
{
SCOPE("Foo")
// stuff
}
I have no idea what you are talking about with regard to enums.
You already noticed what the problem is, an article on boostpro.com sums the problem up.
There are work-arounds, but i'd go for utilizing Boost.Preprocessor.
Without knowing exactly what you're trying to achieve syntactically, something like this might be what you are looking for (edited to PP_SEQ):
#define MAKE_ENUM(Name, Seq) enum Name { BOOST_PP_SEQ_ENUM(Seq) }
MAKE_ENUM(foo, (a)(b)(c));