I would like to print : table_name[variable_value]
by giving ONE input : table_name[variable_name]
Let me explain a simpler case with a toy solution based on a macro:
int i = 1771;
I can print the variable_name with
#define toy_solution(x) cout << #x ;
If I execute
toy_solution(i);
"i" will be printed.
Now, imagine there is a well-allocated table T.
I would like to write in the program:
solution(T[i]);
and to read on the screen "T[1771]".
An ideal solution would treat the two cases, that is :
ideal_solution(i) would print i.
ideal_solution(T[i]) would print T[1771].
It is not important to me to use a macro or a function.
Thanks for your help.
#define toy_solution(x, i) cout << #x << "[" << i << "]"
I would like to print : table_name[variable_value]
by giving ONE input : table_name[variable_name]
well, as you did not understand my comment, I'll say out loud in an answer:
what you want to do is not possible
You have to choose between either #Alin's solution or #lizusek.
I think that #lizusek's solution is better because you're writing C++ code, so if you can do something that gives the same result than with using macros, you should use plain C++ code.
edit: let my try to explain why this is not possible
so what you want is:
f(T[i]) -> T, i
The only way you could write that so it would make sense in preprocessor is:
#define f(T[i]) cout<<#T#<<#i#
but then the preprocessor will give an error, because you can't index an array as a function (even a macro function) parameter:
test.c:5:12: error: expected comma in macro parameter list
#define f(T[i]) cout<<#T#<<#i#
^
If you try to do the same thing using a C++ function, then it's even more non-sense, as a function call such as:
toy_solution(t[i]);
would actually be translated to the value t[i] points to at runtime, so inside the function you'll never be able to known that the given value was actually in an array. So what you want is wrong, and you should stick to good coding practices: using a function and if what you want is:
toy_solution(t[i]);
then use:
toy_solution("t", i);
Possible solutions that you should never use
well, when I say it's not possible, it's that the only solutions I can think off are so twisted that you'd be insane to actually use them in your code… And if you do, I hope I'll never read one of your code or I may become violent :-) That's why I won't show you how or give you any code that could help do what I'm about to tell you.
use a template system
You could either write your code using your own template system or use one commonly used for HTML processing to process your source code through it and apply a transformation rule such as:
toy_solution(t[i]) -> toy_solution("t", t[i])
it's definitely possible, but it makes your build chain even more complicated and dependant on more tools. C/C++ build toolchain are complicated enough, please don't make it worst.
Or you code make your own fork of C and of a C compiler to change the syntax rules so what you want becomes possible. Though, I personnally would never use your fork, and then I'd go trolling and flaming about this on HN, deeply regretting to have given you such a bad idea :-)
use a custom class to encapsulate your arrays in
if you do something like:
template<T>
class Element {
T value;
List<T> _owner;
[…]
}
template<T>
class List {
Element<T> values[];
std::string _name;
[…]
}
so that when you call the function
toy_solution(T[i]);
the implementation would look like:
void toy_solution(Element<T> e) {
std::cout<<e.get_list_name()<<" "<<e.get_value()<<std::endl;
}
but that's sooo much boilerplate and overhead just to avoid doing a simple function definition that does not look as nice as you dream of, that I find it really stupid to do so.
You can write a function as simple as that:
void solution( std::string const& t, int i) {
std::cout << t << "[" << i << "]";
}
usage:
int i = 1771;
solution( "T", i);
You can also write a macro, but be aware that this is not type safe. Function should be preferred.
Related
I'm new to the site and browsed several similar sounding questions but haven't found my exact problem. I suspect I'm making elementary mistakes. A link to an answer would be appreciated, or an explanation, and again I'm sorry if my question doesn't even match the title of the post.
For c++ on the Cxxdroid app for android and in Visual Studio C++:
I'm trying to experiment with classes and namespaces to provide flexible utility to the class. I want to use different implementations of the same function for personal analysis of certain algorithms on data structures; namely arrays vs lists/trees and also between recursive and iterative implementations of standard procedures. I know how to do asymptotic analysis but my stubborn mind wants real numbers.
Unfortunately, however, I can't even seem to get namespace functions to work without blowing up normal functionality. Please note, I haven't learned c++ formally yet because I'm exploring ahead of my introductory c/c++ course.
For example:
#include <iostream>
namespace iterative{
int power(int base,int expo){...}
}
namespace recursive{
int power(int base,int expo){...}
}
int main(int argc,char* argv[]){
int result = 0;
int num = 3;
int exp = 2;
//Expecting 9 in result
std::cout << "This prints fine" << std::endl;
result = iterative::power(num,exp);
std::cout << result;
std::cout << " This number and text doesn't print" << std::endl;
return 1;
}
I had a much more complex function with classes above the namespaced functions (search function for node classes inside a list/tree class) but it never worked. Then I just threw together the above snippet and tried to print result but the std::cout never fired after my function call.
Can anyone offer insight into what I'm doing wrong here? The first cout prints and the second wont. Further, execution hangs during the function call; the solution keeps running until I force it to stop.
I've tried to comment out one of the namespaces while using the other.
I've tried the using keyword with the namespace_name.
I've tried passing integers without variable usage: result = power(3,2);
I've tried printing the function result directly: std::cout << power(3,2) << std::endl;
I can't seem to get it to work on either application. I know this seems like a silly and simple question but after about a week of browsing the internet I'm inundated with very vague answers to questions regarding syntax. Perhaps I'm just not connecting the dots to my own problem...
Is my syntax in definition wrong?
Is my syntax in calling the function wrong?
Is my syntax in variable assignment wrong?
I'm at my wits' end.
Edit:
Now I feel really stupid.
You were correct. I didn't increment my variable in the iterative implementation, which meant it hung up on an infinite loop. I had to print the loop to see the numbers spitting out like I'm Neo in The Matrix. Unfortunately, I didn't test the recursive function because it felt dangerous to do so if I couldn't even get the iterative function to call first...
I was so focused on using namespaces for the first time that I never looked at the loop properly.
Thank you, and sorry for the bother. I'm going to try to extend this experiment to namespace-defining class member functions now.
Edit2: Feel free to delete this...unless it's felt that my stupidity can help others.
Silly mistake was made:
...
int power(int base,int expo){
int i = 0;
int retval = 1;
while( i < expo ){
retval *= base;
//Never did i++; or i = i + 1;
//Had to std::cout << retval; in loop to catch it
}
return retval;
}
...
I would like to use these STL functions in my code, but so many times that their presence makes the readability of the code cumbersome. Is there any way to define "aliases" for these commands?
iomanipulators are functions and to most of them you can easily get a function pointer (actually I didn't check, but for example having several overloads or function templates, would make it less easy):
#include <iostream>
#include <iomanip>
int main(){
auto confu = std::setw;
auto sing = std::setprecision;
std::cout << confu(42) << sing(3) << 42;
}
I cannot help myself but to mention that your motivation is rather questionable. C++ programmers do know stuff from the standard library. The do not know your aliases. Hence for anybody but you readability will be decreased rather than improved. If you have complicated formatting you can wrap the printing in a function:
my_fancy_print(42);
Readers of C++ code are used to functions, they know where to look for their implementation and my_fancy_print(42) is not confusing, while std::cout << confu(42) << sing(3) << 42; is a source of surprise: I would have to look for definition of confu and sing just to realize that they are just aliases for something that could have been used directly.
While upgrading a legacy project to VS2015, I noticed there were a lot of errors where a local variable was redefined inside a function for example.
void fun()
{
int count = applesCount();
cout << "Apples cost= " << count * 1.25;
for (int bag=0; bag<5;bag++)
{
int count = orangesCount(bag);
cout << "Oranges cost = " << count * 0.75;
}
}
The error/warning message by compiler is:
declaration of 'count' hides previous local declaration
I know it is obviously not a good practice to use the same name for variable count but can the compiler really mess things up as well or generally they deal this situation rather gracefully?
Is it worth it to change and fix the variable names or is unlikely to cause any harm and is low or no risk?
I noticed there were a lot of errors where a local variable was redefined inside a function for example.
You are not demonstrating redefining here. You show an example of variable shadowing.
Variable shadowing is not an error syntactically. It is valid and well defined. However, if your intention was to use the variable from the outer scope, then you could consider it a logical error.
but can the compiler really mess things up
No.
The problem with shadowing is that it can be hard to keep track of for the programmer. It is trivial for the compiler. You can find plenty of questions on this very site, stemming from confusion caused by shadowed variables.
It is not too difficult to grok which expression uses which variable in this small function, but imagine the function being dozens of lines and several nested and sequential blocks. If the function is long enough that you cannot see all the different definitions in different scopes at a glance, you are likely to make a misinterpretation.
declaration of 'count' hides previous local declaration
This is a somewhat useful compiler warning. You haven't run out of names, so why not give a unique name for all local variables in the function? However, there is no need to treat this warning as an error. It is merely a suggestion to improve the readability of your program.
In this particular example, you don't need the count in the outer scope after the inner scope opens, so you might as well reuse one variable for both counts.
Is it worth it to change and fix the variable names
Depends on whether you value more short term workload versus long term. Changing the code to use unique, descriptive local variable names is "extra" work now, but every time someone has to understand the program later, unnecessary shadowing will increase the mental challenge.
IMHO, bad coding practice. Hard to maintain and read.
The compiler can discern between the outer variable and the internal variable.
With a good vocabulary (and a thesaurus), one doesn't need to use the same variable names.
Shadowing a variable (which is what this is) has completely well defined semantics, so the compiler won't mess it up. It will do exactly what it has been told, with well defined result.
The problem is (as is often the case) with the humans. It is very easy to make mistakes when reading and modifying the code. If one is not very careful it can be tricky to keep track of which variable with a given name is being referenced and it's easy to make mistakes where you think you are modifying one but in reality you are modifying another.
So, the compiler is fine, the programmer is the problem.
In my experience, compilers usually handle this issue pretty gracefully.
However, it is definitely bad practice, and unless you have a really compelling reason to do so, you should either reuse the old variable (if it logically makes sense to do so), or declare a [differently-named] new variable.
Can be very bad:
Consider this
std::vector<int> indices(100);
if (true) {
std::vector<int> indices(100);
std::iota(indices.begin(), indices.end(), 0);
}
// Now indices will be an all-0 vector instead of the an arithmetic progression!
In Visual Studio, compiling with Warning Level4 /W4 will output a warning even when disambiguating by prefixing with the implicit this pointer, like in this->Count:
warning C4458: declaration of 'Count' hides class member
Although the compiler rarely makes a mistake with the values, shadowing can be abused and get confusing overtime.
Below is an example of shadowing the Count member variable which should be avoided:
From the Unreal Coding Standard document.
class FSomeClass
{
public:
void Func(const int32 Count)
{
for (int32 Count = 0; Count != 10; ++Count)
{
// Use Count
}
}
private:
int32 Count;
}
One option to dealing with this would adding a prefix to the incoming argument name when shadowing occurs, like so:
class FSomeClass
{
public:
void Func(const int32 InCount)
{
Count = InCount;
for (int32 Counter = 0; Counter != 10; ++Counter)
{
// Use Count
}
}
private:
int32 Count;
}
When using RAII resources it may actually simplify the code to shadow variables and not create new variable names.
An example, a simple logger which writes to stdout when entering and leaving a block:
class LogScope {
private:
std::string functionName;
uint32_t lineNo;
public:
LogScope(std::string _functionName, uint32_t _lineNo) :
functionName(_functionName), lineNo(_lineNo) {
std::cout << "Entering scope in " << functionName << " starting line " << lineNo << std::endl;
};
~LogScope(void) {
std:: cout << "Exiting scope in " << functionName << " starting line " << lineNo << std::endl;
};
};
It could be used like:
void someFunction() { // First scope here.
LogScope logScope(__FUNCTION__, __LINE__);
// some code...
// A new block.
// There is really no need to define a new name for LogScope.
{
LogScope logScope(__FUNCTION__, __LINE__);
// some code...
}
}
Having said that, normally it is good practice, not to reuse your variable names.
Zar,
The compiler will handle this situation fine. In your example, the count variable is defined in two different scopes '{}'. Due to the scope of the variable, the assembly language will refer to two different addresses on the stack. The first 'count' might be the stack point, SP-8, while the inner count might be SP-4. Once transformed into an address the name is irrelevant.
I would not generally change working code for stylistic reasons. If the code is a mess then you run the risk of breaking it. Usually messy code doesn't have any good tests so it hard to know if you broke it.
If you need to enhance the code then certainly tidy up.
--Matt
I came across a statement which I didn’t understand. Can anyone explain me please.
It is a C++ program to sort data.
#define PRINT(DATA,N) for(int i=0; i<N; i++) { cout<<"["<<i<<"]"<<DATA[i]<<endl; } cout<<endl;
And also when I tried to rearrange the statement in the below format,I got compilation error!
#define PRINT(DATA,N)
for(int i=0; i<N; i++)
{
cout<<"["<<i<<"]"<<DATA[i]<<endl;
}
cout<<endl;
It's a macro, each time you write PRINT(DATA,N) the pre-processor will substitute it for the entire for loop, including the variables.
You're missing \ signs at the end of each line. This tells it the Macro continues to the next line. (Look at Multi-statement Macros in C++
If you use macro, use brackets around any variables (DATA) and (N). The substitution is literal and this will allow usages like PRINT(data, x+1) which otherwise cause unexpected results.
Don't use macro unless you REALLY must, there are many problems that can arise from this, it doesn't have a scope and so on. You can write an inline method or use std::copy_n like Nawaz proposed
It can be used if you properly define it. But .... just because it can be used, does not mean that it should be used.
Use std::copy_n:
std::copy_n(data, n, std::stream_iterator<X>(std::cout, " "));
That will print all the n items from data to the stdout, each separated by a space. Note that in the above code, X is the type of data[i].
Or write a proper function (not macro) to print in your own defined format. Preferably a function template with begin and end as function parameters. Have a look at how algorithms from the Standard library work and are implemented. That will help you to come up with a good generic design of your code. Explore and experiment with the library generic functions!
This isn't something you want to use a macro for.
Write a template function that does the exact same thing:
template<typename T>
void PRINT(const T &data, size_t n){
for (size_t i=0;i<n;++i)
cout << "["<<i<<"]"<<data[i]<<endl;
}
You should really avoid using macros. The only reason I find you NEED macros is when you need to use the name of the input (as string), or location (LINE or FILE) e.g.:
#define OUT(x) #x<<"="<<x<<"; "
#define DEB std::cerr<<"In "<<__FILE__<<":"<<__LINE__<<": "
for use in printing like this:
DEB << OUT(i)<<OUT(val[i])<<OUT(some_func(val[i],3))<<endl;
Which will print
In file.cc:153: i=4; val[i]=10; some_func(val[i],3)=4.32;
This is a functionality you can't do without macros. Anything you CAN do without macros you SHOULD
To print debug messages in my program, I have a that can be used like this:
DBG(5) << "Foobar" << std::endl;
5 means the level of the message, if the debug level is smaller than 5, it won't print the message. Currently it is implemented like:
#define DBG(level) !::Logger::IsToDebug((level)) ? : ::Logger::Debug
Basically IsToDebug checks if the message should be printed, and returns true when it should. Logger::Debug is an std::ostream. This works with gcc and clang too, however clang generates expression result unused warnings. According to this email this doesn't like to change either.
Prefixing it with (void) doesn't work, it will only cast the thing before the ?, resulting in a compilation error (void can't be converted to bool, obviously). The other problem with this syntax that it uses a gcc extension.
Doing things like #define DBG(x) if (::Logger::IsToDebug((x))) ::Logger::Debug solves the problem, but it's a sure way break your program (if (foo) DBG(1) << "foo"; else ...) (and I can't put the whole thing into a do { ... } while(0) due to how the macro is called.)
The only more or less viable solution I came up with is this (assuming IsToDebug returns either 0 or 1):
#define DBG(level) for(int dbgtmpvar = ::Logger::IsToDebug((level)); \
dbgtmpvar > 0; --dbgtmpvar) ::Logger::Debug
Which seems like an overkill (not counting it's runtime overhead)
I think you should use ternary operator, as it is defined in the Standard, rather than compiler extension. To use the Standard ternary operator, you've to provide the second expression as well. For that, you can define a stream class, deriving from std::ostream which doesn't print anything to anywhere. Object of such a class can be used as second expression.
class oemptystream : std::ostream
{
//..
};
extern oemptystream nout; //declaration here, as definition should go to .cpp
then
#define DBG(level) ::Logger::IsToDebug((level))? nout : ::Logger::Debug
Now if you use this macro, then at runtime, the expression would reduce to either this:
nout << "message";
Or this,
::Logger::Debug << "message";
Either way, it is pretty much like this:
std::cout << "message";
So I hope it shouldn't give compiler warning.