I read code in buf0buf.cc of mysql's innodb buffer source code here:
link from git hub
And I got this:
&buf_pool->watch[0]
What is the value of the statement? address? or another value?
What does the code mean?(grammar meaning)
Due to operator precedence, this expression is parsed like:
&( (buf_pool->watch)[0] )
In English, the value is the address of the first element of the watch member container in buf_pool.
You can find out.
First of all, let's take the buf_bool variable and look for its declaration. As you can see a few lines above, it's a function parameter:
const buf_pool_t* buf_pool
This means we have to find the definition of the buf_pool_t type. With a mere full-text search, the type definition is not revealed. However, googling for "mysql buf_pool_t" gets us to http://www.iskm.org/mysql56/structbuf__pool__t.html, which in turn tells us that the type is defined in a file called buf0buf.h. That one's also included in the source file you've linked to:
#include "buf0buf.h"
It does indeed contain the definition we are looking for, and that definition includes a member called watch:
struct buf_pool_t{
(...)
buf_page_t* watch;
(...)
};
watch is a pointer to buf_page_t.
So if we go back to the statement in your question:
&buf_pool->watch[0]
watch is interpreted as a pointer to the first element of a buf_page_t array, watch[0] is the first element itself, and the address-of operator yields a pointer to that first element.
So the whole statement reads as:
a pointer to the first element of a buf_page_t array.
Curiously, &buf_pool->watch[0] is equal to buf_pool->watch. Here is a simple (C++11) toy program to verify all of this:
#include <iostream>
#include <typeinfo>
using buf_page_t = int;
struct buf_pool_t {
buf_page_t* watch;
};
int main()
{
const buf_pool_t example = { new buf_page_t[1] };
const buf_pool_t* buf_pool = &example;
std::cout << typeid(&buf_pool->watch[0]).name() << "\n";
std::cout << typeid(buf_pool->watch).name() << "\n";
std::cout << (&buf_pool->watch[0] == buf_pool->watch) << "\n"; // prints 1
}
&buf_pool->watch[0] is the the address of the member 0 of watch contained in the struct buf_bool. Which is watch itself.
It is parsed like that because the whole buf_pool->watch[0] gets under the & (address of) sign.
You can check with this snippet:
#include <iostream>
#include <stdio.h>
using namespace std;
struct hello_t
{
int before;
int array[5];
};
int main() {
// your code goes here
struct hello_t hello;
hello.array[0] = 100;
struct hello_t* ptr_hello;
ptr_hello = &hello;
printf("ptr_hello = %X\n", ptr_hello);
printf("&ptr_hello = %X\n", &ptr_hello);
printf("&ptr_hello->before = %X\n", &ptr_hello->before);
printf("&ptr_hello->array[0] = %X\n", &ptr_hello->array[0]);
printf("");
return 0;
}
https://ideone.com/fwDnoz
Related
I am using libtidy and need to retrieve the current value of a string-based option (for example, TidyOptErrFile, a.k.a. error-file).
Even after reading through the tidy source code, I cannot figure out which function to use to read the current value of such an option.
The TidyOptGetVal() function seemed promising, but no matter what I do, it always returns a null pointer. Here is my minimalist attempt (in C++ so I can use the auto keyword):
#include <iostream>
#include <tidy.h>
#include <tidybuffio.h>
#include <tidyenum.h>
using namespace std;
int main(int argc, const char * argv[]) {
auto tidyDoc = tidyCreate();
// The following should set the `error-file` property to `Foobar`
tidyOptParseValue(tidyDoc, "TidyErrFile", "Foobar");
// The type is `ctmbstr` which is just an alias for `const char*`
auto errorFile = tidyOptGetValue(tidyDoc, TidyErrFile);
if (errorFile==nullptr) {
cout << "Null pointer" << endl;
} else {
cout << errorFile << endl;
}
tidyRelease(tidyDoc);
return 0;
}
I found the reason for the problem, which I will post for future reference.
The function tidyOptParseValue() takes as its second argument the name of the option as given in the API.
So, for example, the option name in this case should be error-file (not the name of the enumeration found in the source code).
The corrected line should be
tidyOptParseValue(tidyDoc, "error-file", "Foobar");
Using that fix, the word Foobar is printed, as expected.
I am using C language to upgrade my coding skills.
I designed a simple program because I wanted to easily find the problems what I looked for and arrange the works when I handle many problems as shown in below.
Here is my header file
#pragma once
#ifndef PROBLEM_H
#define PROBLEM_H
namespace PROBLEM_1 { int do_main(); }
typedef int(*MAINFUNC)();
#endif
And below is my source file.
#include "problems.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
typedef int(*MAINFUNC)(void);
map<string, MAINFUNC> func_map;
void initialize_problem_map(void) {
func_map["problem_1"] = PROBLEM_1::do_main;
}
namespace PROBLEM_1 {
int do_main(void) {
cout << "hi" << endl;
return 1;
}
}
int main(void) {
string problem;
initialize_problem_map();
cin >> problem;
if (func_map.find(problem) != func_map.end())
return (*(func_map[problem]))();
return -1;
}
If I input "PROBLEM_1" then, the do_main functions in namespace PROBLEM_1 will be executed. I think that this design helps me organize multiple coding problems.
However, my question is about these two code lines as below.
if (func_map.find(problem) != func_map.end())
return (*(func_map[problem]))();
As you can see, the main fucntion's return type is "int". However, in the if-clause, i think that it return function-pointer. Therefore, I thought that those returning behavior is mismatched with the main function's return type. But, to my surprise, it worked well.
Could u explain this procedures regarding returning types?
func_map[problem], indeed, results in a function pointer. Applying the operator () on it, the function is invoked and the expression results in an int. Dereferencing a function pointer before its invocation is optional. This is symmetric with an optional address taking on a function name for initializing function pointers.
Indeed
func_map[problem]
is a pointer. However, you dereference the pointer with *:
*(func_map[problem])
and call function by adding ():
(*(func_map[problem]))()
which returns "int".
find returns an iterator; if this iterator is end, then the problem does not exist in the map; Because it is not end, it exists, then in the return line the pointer function obtained with [] is used to call it.
I've got this code:
#include <iostream>
int tabela[1];
tabela[0] = 1;
int main(){
std::cout << tabela[0];
std::cin.get();
return 0;
}
and it doesn't want to work. My compiler says " "tabela" doesn't name a type".
However if I do this:
#include <iostream>
int tabela[1];
int main(){
tabela[0] = 1;
std::cout << tabela[0];
std::cin.get();
return 0;
}
It works. Can sb explain me why? Thanks in advance.
At the outermost level, a C++ file is a sequence of declarations. tabela[0] = 1; is not a declaration - it's a statement (in particular an expression-statement). A function body, however, is a sequence of statements, so it's fine to put this line inside the body of main (or any other function).
Some statements are declarations (called declaration-statements), but in general they're not.
for it to be valid C++, you can only initialize variables in global, you can't assign them there.
edit: comments beat me to it. props
I am a java programmer trying to teach myself c++. Please cut me a little slack if I ask simple questions at first.
I would like to understand how the structure dereference operator works. Specifically, can anyone tell me what the following line of code does in explicit terms?
if (elements[i]->test(arga, argb)) {}
test(arga,argb) is a Boolean function in the same class, and elements is a vector of instances of the element class. Here is the code that immediately surrounds the line above, about which I am interested:
for (unsigned i = 0; i < elements.size(); ++i) {
T arga = INFINITY, argb = INFINITY;
//using namespace std;
//std::cout >> elements[i] >> std::endl;
//std::cout >> test(arga, argb) >> std::endl;
if (elements[i]->test(arga, argb)) {
//some code
}
}
It seems that the if line is testing to see whether or not the boolean returned by test(arga,argb) is part of the given instance of the elements class. But when I try to expose the underlying values of elements[i] or test(arga,argb) with the cout lines above, the compiler throws errors until I comment those lines out. In java, I would be able to fiddle around with this until I found values of each that correspond with each other, and then I would understand the line of code. But I do not know how to figure out what this line of code does in C++. Can anyone give me a clear explanation, preferably supported by a link or two to some references online?
elements[i]->test (arga, argb)
If we break down the statement, reading from left-to-right, we will end up with the below:
access the ith element in an array (or array-like) entity named elements
the element accessed (elements[i]) is a pointer to an object
call the member-function named test on elements[i] and pass it two arguments; arga and argb
if we disregard the fact that you wrote std::cout >> instead of std::cout << (the latter is the correct form), we end up with two reasons for your described errors:
your compiler complains about std::cout << element[i] because no suitable overload is found to handle an entity of the type of element[i] and an std::ostream& (which is the underlying type of std::cout).
your compiler complains about std::cout << test (arga, argb) because there is no function in scope named test that takes two arguments corresponding to arga, argv. test, in your snippet, is a member-function that belongs to an entity, it's not callable by its own.
Welcome to C++.
First, the syntax for output is:
cout<<
instead of
cout>>
You are right in guessing that test is a function that returns boolean.Here elements[i] is a pointer pointing to a struct element which has this test function.
To learn C++, you can use these articles that I wrote.Good luck!
Since numerous respondents told me that I need to provide the code before they can answer, I looked deeper in the code, and re-wrote something which tells me that the line:
if (elements[i]->test(arga, argb)) {}
is a test to see whether or not the boolean member function of elements[i] is true.
The c++ program that I wrote to identify the meaning of -> in this context is:
#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
template<typename T>
class Bone
{
public:
std::string myName;
int mySize;
Bone(const std::string &name, const int &size) : myName(name), mySize(size)
{}
bool isBigger(const int &testSize) const
{
if (testSize > mySize) return false;
else return true;
}
};
int main(int argc, char **argv)
{
std::vector<Bone<float> *> bones;
// name, location, size
bones.push_back(new Bone<float>("femur", 10));
bones.push_back(new Bone<float>("ulna", 4));
bones.push_back(new Bone<float>("maxilla", 3));
int testSize = 6;
// test each bone to see if it is bigger than testSize
for (unsigned i = 0; i < bones.size(); ++i) {
if (bones[i]->isBigger(testSize)) {
std::cout << bones[i]->myName; std::cout << " is bigger than testSize! " << std::endl;
}
}
while (!bones.empty()) {
Bone<float> *thisBone = bones.back();
bones.pop_back();
delete thisBone;
}
return 0;
}
Thank you to everyone who led me to figure this out.
I have a method that takes in a reference to a vector that contains pointers to objects as the first parameter, and a reference to a pointer to an object of the same type as the second parameter. Within the method, I want to change the location referenced by the second argument to an object within the vector. Then have the changed pointer be used by the caller of the method, having the new location as its target. However, my current attempts at implementing this are failing.
The method in question:
void execute(std::vector<CanvasElement*>& elements,CanvasElement*& lastFocused)
Examples of ways I've unsuccessfully tried setting the value pointed to by lastFocused:
lastFocused = elements[0];
*lastFocused = *elements[0];
An elaboration in reply to a comment below:
The failure is that the changes inside the function are not reflected once outside the scope of that function.
I can confirm by printing the addresses stored in each pointer during the application's runtime, that the value is indeed being set within execute, but outside of execute it wasn't changed.
The assignment lastFocused = elements[0]; should work, here is a demonstration:
#include <iostream>
#include <string>
#include <vector>
typedef std::string CanvasElement;
void execute(std::vector<CanvasElement*>& elements, CanvasElement*& lastFocused)
{
lastFocused = elements[0];
}
int main()
{
std::string a = "hello";
std::string b = "world";
std::vector<std::string*> vec;
vec.push_back(&a);
vec.push_back(&b);
std::string* p = 0;
execute(vec, p);
if (p == &a)
{
std::cout << "It worked :-)\n";
}
else
{
std::cout << "It did not work :-(\n";
}
}
By the way, there are people who would argue that the following signature would be better:
CanvasElement* lastFocusedCanvasElement(std::vector<CanvasElement*>& elements)
That is, you should return a pointer value instead of changing a pointer variable.
I was able to solve this problem by storing a reference to the pointer in a vector and updating that stored reference. I do not know why setting it directly did not work, but this hack got the job done.