Can we set a GDB breakpoint on a function such that it will break into only if the function argument matches the value specified?
Ex
int foo(int i) {
return i*i;
}
int main() {
foo(0);
................
foo(9);
}
How do I set a breakpoint on foo only when the argument i of foo is 5?
Sure, use "break if"
break foo if i == 5
If you have multiple variable if need to break on, just use classic if syntax :
break foo if i == 5 && j == 3
Related
Given the common while() statement in both do ... while and while loops, and the way the place where a while loop's body would be replaced with a semicolon on a do ... while as if it's a compound statement being turned into an empty statement (or ending the line of a long statement):
Does the syntax in any of the C family languages allow for a "do while and while" loop with both bodies defined?
Presumably the semantics would be a single loop with some operations occurring before the check and some after.
For example:
do {
foo();
} while ( baz() == true ){
bar();
}
foo() would always occur once but bar() would only occur after if baz() returned true.
They cannot be used at the same time. The syntax is either:
while ( expression ) statement
or:
do statement while ( expression ) ;
So you can't do this as in your example:
do {
foo();
} while ( baz() == true ){
bar();
}
But you can come close with this:
do {
foo();
if (!baz()) break;
bar();
} while (1);
You seem to be asking for
do
statement0
while (condition)
statement1
This can be accomplished with:
do
{
statement0
if (!(condition)) break;
statement1
} while (1);
In C or C++, Can a loop have both “do” and “while” sections?
Does the syntax in any of the C family languages allow for a "do while and while" loop with both bodies defined?
No, you can either have a while loop or a do-while loop. A while loop is something different than a do-while loop and vice versa.
You can not merge both types together.
It can only be a do-while loop:
do
{
/* statements */
}while(condition);
or a while loop:
while(condition)
{
/* statements */
};
At the while loop, you execute statements after a certain condition. At the do while loop you run at least once through the loop until it reaches the condition. But the center of both loops is at the end the same kind of statements/loop body. Thus, It would make no sense to add a second one.
When you use a do-while loop, like the way you have made:
do {
foo();
} while ( baz() == true ){
bar();
}
the area enclosed by {} after the do-while loop condition of:
{
bar();
}
is not part of the do-while loop.
It will be treated as only a bunch of statements in a separate scope block which will get executed after the do-while-loop is fulfilled/done.
But even then, the compiler will only let this pass, if you have set the semicolon ; after the do-while-loop condition:
do {
foo();
} while ( baz() == true );{ // Note the semicolon ";".
bar();
}
With the provided code of:
do {
foo();
} while ( baz() == true ){
bar();
}
the compiler will throw an error.
Both do and while blocks in the same loop are not allowed in C or C++.
It is not allowed in any other programming language as well.
class foo {
std::vector<int> datas;
public:
template <typename It>
foo(It x, It y) {
for(; x != y; ++x)
insert(*x);
}
void insert(int val) {
if(val == 5)
throw 99;
else
datas.push_back(val);
}
void print() const {
for(int x : datas)
std::cout << x << " ";
}
};
int main() {
std::vector<int> v{1, 2, 3, 5, 6, 7};
foo* f;
try {
f = new foo(std::begin(v), std::end(v));
}catch(int const& x) {
}
f->print();
}
I suppose that f wouldn't be constructed in this case; the exception thrown by the insert method is not handled in the body of foo constructor.
I got the following output on gcc 8.2.0 :
1 2 3 5 6 7
I suppose that f wouldn't be constructed in this case;
A foo instance would not be constructed in this case.
Furthermore, f would not have been assigned to, so its value would remain indeterminate.
Is this a right behavior?
Accessing an object by indirecting through an indeterminate pointer has undefined behaviour.
While the undefined nature has been discussed, I feel like it might be interesting to look into actual produced result and speculate why we see it.
While I have no proof, I believe it is an interesting consequence of compiler optimizations and code reasoning. We see that the output is 1 2 3 5 6 7, even though the code has a throw statement for element 5. How would this happen?
In my view, since we have f->print() outside of try block, compiler reasons that f is never uninitialized - so constructor never throws. Since constructor never throws, val == 5 is never true! Because of that, the branch is removed. And thus we have the result we do have.
I'm trying to print the return value of a templated member function in gdb (version 7.6.1 I think) of an rvalue reference, so what I write in gdb amounts to something like this:
gdb> print (*(TypeOne*)var).get<TypeTwo>()
I've tried parenthesizing various parts of the expression with no success, and I wasnt able to find any other question on this. Anyone know?
Starting from this related post: How to `print`/evaluate c++ template functions in gdb
I was able to figure out how to do this within my own program.
I'm not using an rvalue nor a variant so it may not work for that, but I think it's still relevant to this question.
My use case was a method with a single enum as a template parameter, similar to this:
#include <stdio.h>
enum class MyEnum {
VALUE_0 = 0,
VALUE_1 = 1
};
struct TestStruct {
template <MyEnum VALUE>
int getValue() {
if constexpr (VALUE == MyEnum::VALUE_0) {
return value_0;
} else /* VALUE == MyEnum::VALUE_1 */ {
return value_1;
}
}
const int value_0 = 7;
const int value_1 = 9;
};
int main()
{
TestStruct test;
test.template getValue<MyEnum::VALUE_0>();
test.template getValue<MyEnum::VALUE_1>();
return 0;
}
If we use ptype on the object we get a list of methods on the object:
(gdb) b 36
Breakpoint 1 at 0x4004f7: file main.cpp, line 36.
(gdb) r
Starting program: /home/a.out
Breakpoint 1, main () at main.cpp:36
36 return 0;
(gdb) ptype test
type = struct TestStruct {
const int value_0;
const int value_1;
public:
int getValue<(MyEnum)1>(void);
int getValue<(MyEnum)0>(void);
}
If we want to call this method:
int getValue<(MyEnum)1>(void);
We can call it by using the name exactly as shown, in single quotes.
(gdb) p test.'getValue<(MyEnum)1>'()
$1 = 9
You can try it here: https://onlinegdb.com/7OtaUvK3g
Note from the other thread:
Without an explicit instance in the source code, the compiler will treat the template code as it would "static inline" code and optimize it out if it is unused.
So you must call the method somewhere in your code to be able to call it in gdb at all, this will not work otherwise.
To make it short, here is a minimal example:
struct C {
const int X = 2;
int y = 2;
};
void f(C* x) {
switch(x->y) {
case x->X: printf("%d", 42); break;
case 123: printf("foo");
}
}
int main()
{
C c;
f(&c);
return 0;
}
Why is the compiler complaining error: 'x' is not a constant expression and how to fix it?
Case labels inside switch accept only compile-time constant expressions. x->X is not a constant expression; hence it could not be used as a case label.
Replace the switch statement with an if to fix this problem:
if (x->y == x->X) {
printf("%d", 42);
} else if (x->y == 123) {
printf("foo");
}
In main, you declare an instance of C and pass it to f. According to the definition of f, it does not guarantee that c does not get changed - and main has no way to verify it.
I think f needs to be f(C * const x);
The given code (modulo formatting)
struct C
{
int const x = 2;
int y = 2;
};
… means this:
struct C
{
int const x;
int y;
C(): x( 2 ), y( 2 ) {}
};
… i.e. the members are initialized by each constructor.
You can even override that initialization in a user defined constructor:
struct S
{
int const x = 2;
S(): x( 3 ) {}
};
Here in every instance x will be 3.
And so x isn't a compile time constant. It's very much a run time thing. And as such it can't be used as a case label in a switch, because a case label must be a value known at compile time. In turn because the switch construct is designed to be efficiently implemented as simple array indexing (a computed jump) when the value range permits that.
One simple fix is to define the relevant value as a compile time constant. Either as a static or enum value inside the class. Or outside the class.
Another possible fix is to use an if-else ladder instead of a switch.
Case accepts Constant Expression,like 2 or 'a'.And Const just define an unchanging variant.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Here is the code
int& fun(){
static int x = 10;
return x;
}
int main() {
fun() = 30;
cout<< fun();
getch();
}
The output is 30.
How does this work?
Let's read it line by line:
int& fun()
declares a function named fun which returns a reference to an integer variable
{
static int x = 10;
The x variable is static inside this function. A special place in memory is reserved for it and is initialized with 10. Every time this function is called x will get the value stored in that special location.
return x;
}
We return x and leave the function. Let's go to the main one:
int main()
{
fun() = 30;
Remember that fun returns the reference to an int. Here we modify the integer to be 30. Since this integer has static allocation every time fun will be called from now on x will start with 30, unless other changes are made.
cout<< fun();
Since x is 30 that's what you get.
getch();
}
Suggestion: use GDB and trace the program's execution step-by step:
$ gdb ./a.out
(gdb) b main
Breakpoint 1 at 0x40077b: file 1.cpp, line 11.
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, main () at 1.cpp:11
11 fun() = 30;
We start GDB, set a breakpoint at the begining of main and start the program.
(gdb) disp fun()
1: fun() = (int &) #0x60104c: 10
Since fun returns a reference to a static variable I can display it's value at each step in GDB.
(gdb) s
fun () at 1.cpp:6
6 return x;
1: fun() = (int &) #0x60104c: 10
Running a single step we see that we are in func. This is the place where x is returned (as a reference) to be attributed 30.
(gdb) n
7 }
1: fun() = (int &) #0x60104c: 30
Indeed, after leaving the function, x is 30.
(gdb)
main () at 1.cpp:13
13 cout<< fun();
1: fun() = (int &) #0x60104c: 30
(gdb) s
fun () at 1.cpp:6
6 return x;
1: fun() = (int &) #0x60104c: 30
(gdb)
7 }
1: fun() = (int &) #0x60104c: 30
(gdb)
main () at 1.cpp:15
15 }
1: fun() = (int &) #0x60104c: 30
(gdb) q
We continue the program's execution and leave GDB (though your question is already answered).
It is straightforward : fun returns the reference to the static variable inside the function, which is assigned to 30 by this line:
fun() = 30;
this means, x inside the function is changed to 30. What is more? It is 30! You print it by calling again fun() in the next line.
Note that a static variable lives till the end of the program: it is not destroyed even if the function returns!
The fun function returns a reference-to an int type. This way, when you call fun() = 30, you actually set x to 30.
This way when you print it out, the fun function will no longer set it, cause that is a one-off declaration.