I roughly understand the rules with what #include does with the C preprocessor, but I don't understand it completely. Right now, I have two header files, Move.h and Board.h that both typedef their respective type (Move and Board). In both header files, I need to reference the type defined in the other header file.
Right now I have #include "Move.h" in Board.h and #include "Board.h" in Move.h. When I compile though, gcc flips out and gives me a long (what looks like infinite recursive) error message flipping between Move.h and Board.h.
How do I include these files so that I'm not recursively including indefinitely?
You need to look into forward declarations, you have created an infinite loops of includes, forward declarations are the proper solution.
Here's an example:
Move.h
#ifndef MOVE_H_
#define MOVE_H_
struct board; /* forward declaration */
struct move {
struct board *m_board; /* note it's a pointer so the compiler doesn't
* need the full definition of struct board yet...
* make sure you set it to something!*/
};
#endif
Board.h
#ifndef BOARD_H_
#define BOARD_H_
#include "Move.h"
struct board {
struct move m_move; /* one of the two can be a full definition */
};
#endif
main.c
#include "Board.h"
int main() { ... }
Note: whenever you create a "Board", you will need to do something like this (there are a few ways, here's an example):
struct board *b = malloc(sizeof(struct board));
b->m_move.m_board = b; /* make the move's board point
* to the board it's associated with */
Include guards would be part of the solution to this issue.
Example from wikipedia:
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct foo {
int member;
};
#endif
http://en.wikipedia.org/wiki/Include_guard
The other part as noted by several others is forward referencing. (http://en.wikipedia.org/wiki/Forward_Reference)
You can partially declare one of the structures above the other one like so:
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct bar;
struct foo {
int member;
};
#endif
Like so:
//Board.h
#ifndef BOARD_H
#define BOARD_H
strunct move_t; //forward declaration
typedef struct move_t Move;
//...
#endif //BOARD_H
//Move.h
#ifndef MOVE_H
#define MOVE_H
#include "Move.h"
typedef struct board_t Board;
//...
#endif //MOVE_H
This way Board.h can be compiled without dependency on move.h and you can include board.h from move.h to make its content available there.
First, you seem to lack include guards in your .h files, so you're including them recursively. That is bad.
Second, you can do a forward declaration. In Move.h:
/* Include guard to make sure your header files are idempotent */
#ifndef H_MOVE_
#define H_MOVE_
#include "Board.h"
/* Now you can use struct Board */
struct Move { struct Board *board; };
#endif
In Board.h:
#ifndef H_BOARD_
#define H_BOARD_
struct Move; /* Forward declaration. YOu can use a pointer to
struct Move from now on, but the type itself is incomplete,
so you can't declare an object of the type itself. */
struct Board { struct Move *move; }; /* OK: since move is a pointer */
#endif
Note that if you need to declare struct Move and struct Board objects (rather than pointer to one of them) in both the files, this method won't work. This is because one of the types is an incomplete type at the time of parsing of one of the files (struct Move in the above example).
So, if you need to use the types in both the files, you will have to separate out the type definitions: have header files that define struct Move and struct Board, and nothing else (something like my example above), and then use another header file that references both struct Move and struct Board.
Of course, you can't have struct Move contain a struct Board and struct Board contain a struct Move at the same time—that will be infinite recursion, and the struct sizes will be infinite as well!
You need to have one of them first. Make a forward decl in one of them and have that one for for example
#ifndef move
struct move;
#endif
could be part of the board.h file.
and
#ifndef board
struct board;
#endif
could be part of the move.h file
then you could add them in either order.
edit
As was pointed out in the comments... I was assuming the use of the typedef construct as follows for the board struct
typedef struct {…} board;
since I've never seen anyone using structs in C without a typedef I made this assumption... maybe things have changed since the last time I coded in C (yikies.... it was like 15 years ago)
Circular dependencies are a pain in the ass and should be eliminated wherever feasible. In addition to the forward declaration suggestions given so far (Alok's is the best example), I'd like to throw another suggestion into the works: break the mutual dependency between Board and Move by introducing a third type (call it BoardMoveAssoc for illustration; I'm sure you can come up with a less sucky name):
#ifndef H_BOARD_MOVE_ASSOC
#define H_BOARD_MOVE_ASSOC
#include "Move.h"
#include "Board.h"
struct BoardMoveAssoc {
Move m;
Board b;
};
...
#endif
Under this scheme, Board and Move don't have to know anything about each other; any associations between the two are managed by the BoardMoveAssoc type. The exact structure will depend on how Move and Board are supposed to be related; e.g., if multiple moves are mapped to a single board, the structure may look more like
struct BoardMoveAssoc {
Move m[NUM_MOVES] // or Move *m;
Board b;
};
This way, you don't have to worry about forward declarations or incomplete types. You are introducing a third type into the mix, but I believe this will be easier to understand and maintain.
From K&R The C Programming Language (p 91 "Conditional Inclusion" in my copy), with some tweaks for you:
#if !defined (BOARD_H)
#define BOARD_H
/* contents of board.h go here */
#endif
and the same for Move.h
In this way, once a header has been included once, it will not be included again, as the 'BOARD_H' name has already been defined for the preprocessor.
Related
I learned that from C++17, with the deduction guides, template arguments of std::vector can be deduced e.g. from the initialization:
std::vector vec = { function_that_calculate_and_return_a_specifically_templated_type() }
However I do not have the luxury of C++17 in the machine where I want to compile and run the code now.
Is there any possible workaround for C++11? If more solutions exist, the best would be the one that keep the readability of the code.
At the moment the only idea that I have is to track the various cases along the code (luckily they should not be too many) and make some explicit typedef/using.
Any suggestion is very welcome
The usual way to use type deduction for class template when CTAD is not available is providing a make_* function template, e.g. for your case (trailing return type is necessary for C++11):
#include <vector>
#include <type_traits>
#include <tuple>
template <class ...Args>
auto make_vec(Args&&... args) ->
std::vector<typename std::decay<typename std::tuple_element<0, std::tuple<Args...>>::type>::type>
{
using First = typename std::decay<typename std::tuple_element<0, std::tuple<Args...>>::type>::type;
return std::vector<First>{std::forward<Args>(args)...};
}
You can invoke the above with
const auto v = make_vec(1, 2, 3);
which gets at least kind of close to CTAD in the sense that you don't have to explicitly specify the vector instantiation.
While the answer by lubgr is a correct way, the following template is simpler and seems to work as well:
#include <vector>
#include <string>
template <typename T>
std::vector<T> make_vec(const std::initializer_list<T> &list)
{
return std::vector<T>(list);
}
int main()
{
auto v = make_vec({1,2,3});
auto v2 = make_vec({std::string("s")});
std::string s("t");
auto v3 = make_vec({s});
return v.size() + v2.size() + v3.size();
}
One advantage of using the initializer_list template directly are more clear error messages if you pass mixed types like in make_vec({1,2,"x"});, because the construction of the invalid initializer list now happens in non-templated code.
Using C++11, g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18).
Lets pretend I have a templated function (pardon my terminology if it isn't quite right).
I want to perform a "general" algorithm based on what was supposed to be compile-time instances of "field". Where the only things that really changed are these constants which I moved into trait classes (only added one here but imagine there are more). Originally I was declaring it as
constexpr field FIELD1{1};
However in C++11, non-type template params need to have external linkage (unlike C++14 which can have internal and external linkage?). So because not's in the same translation unit I needed to use extern in order to give it external linkage (sorry if I butchered that explanation also). But by defining it extern I can't define it using constexpr and it seems that losing that constexpr constructor this field is no longer a valid constant expression to qualify as a non-type template param.
Any suggestions if there is some way I can get around this? Open to a new method of doing things. Below is a simplified (incomplete, and non-compiling version to get the gist of the organization).
So the error I am seeing is along the lines of
error: the value of ‘FIELD1’ is not usable in a constant expression
note: ‘FIELD1’ was not declared ‘constexpr’
extern const field FIELD1;
Not quite sure what could be a best alternative.
I can get rid of the second error by removing the constexpr from the constructor. But then I don't know how to approach the constant expression issue.
field.H
struct field
{
int thingone;
constexpr field(int i):thingone(i){}
};
extern const field FIELD1;
field.C
#include "field.H"
const field FIELD1{0};
field_traits.H
#include "field.H"
template< const field& T >
class fieldTraits;
template< >
class fieldTraits<FIELD1>
{
public:
// Let's say I have common field names
// with different constants that I want to plug
// into the "function_name" algorithm
static constexpr size_t field_val = 1;
};
function.H
#include "field.H"
template< const field& T, typename TT = fieldTraits<T> >
void function_name()
{
// Let's pretend I'm doing something useful with that data
std::cout << T.thingone << std::endl;
std::cout << TT::field_val << std::endl;
}
So because not's in the same translation unit I needed to use extern in order to give it external linkage (sorry if I butchered that explanation also). But by defining it extern I can't define it using constexpr [...]
Per my comment, you can. It wouldn't work for you, but it's a step that helps in coming up with something that would work:
extern constexpr int i = 10;
This is perfectly valid, gives i external linkage, and makes i usable in constant expressions.
But it doesn't allow multiple definitions, so it can't work in a header file which is included in multiple translation units.
Ordinarily, the way around that is with inline:
extern inline constexpr int i = 10;
But variables cannot be declared inline in C++11.
Except... when they don't need to be declared inline because the effect has already been achieved implicitly:
struct S {
static constexpr int i = 10;
};
Now, S::i has external linkage and is usable in constant expressions!
You may not even need to define your own class for this, depending on the constant's type: consider std::integral_constant. You can write
using i = std::integral_constant<int, 10>;
and now i::value will do exactly what you want.
It seems that top level objects in gcc targeting x86 that are >= 32 bytes automatically get 32 byte alignment. This may be nice for performance, but I'm collecting an array of thingies from all my object files in a user-defined section, and the extra alignment gaps play havoc with this array. Is there any way to prevent this object alignment?
To clarify, I have a low-aligned struct, and different object files define
data in the form of an array of that struct in a user defined section, with
the purpose to make one application wide array.
As soon as one of those arrays is >= 32, the object alignment and with that the section alignment is pushed to 32 and when the linker concatenates the separate sections from the object files into the executable, it creates alignment fillers at the module boundaries in that section.
The following program illustrates a possible solution, assuming GCC
extensions are acceptable to you:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ALIGNMENT // __attribute__ ((aligned (8)))
struct A {
char arr[40];
} ;
struct A a __attribute__ ((section ("my_data"))) ALIGNMENT = {{'a'}};
struct A b __attribute__ ((section ("my_data"))) ALIGNMENT = {{'b'}};
struct A c __attribute__ ((section ("my_data"))) ALIGNMENT = {{'c'}};
int main(int argc, char **argv)
{
assert(sizeof(struct A) == 40);
printf("%c\n",a.arr[0]);
printf("%c\n",b.arr[0]);
printf("%c\n",c.arr[0]);
printf("%lu\n",(unsigned long)(&a));
printf("%lu\n",(unsigned long)(&b));
printf("%lu\n",(unsigned long)(&c));
return 0;
}
My output is:
a
b
c
6295616
6295680
6295744
Note that in my (64-bit) executable each of the three 40-byte structures
is 64-byte aligned.
Now uncomment // __attribute__ ((aligned (8))), rebuild and rerun. My
output then is:
a
b
c
6295616
6295656
6295696
Now the structures are 8-byte aligned, without gaps.
I have a (large) C/C++ project that consists of both C and C++ languages. At some point it turned out that there are two C functions with identical names. Those functions are defined in two different *.c files in different locations. In general at the highest level, the project is C++. This problem was questioned and answered here
However still a question "how to organize those files safely" remains. How can I group such project so that there are no name conflicts, and I can be sure that proper function is called. Will writing a wrapper for each of those functions help?
That how it looks at the moment:
A.h //first declaration of function F
A.c //first definition of function F
B.h //second declaration of function F
B.c //second definition of function F
trying to make such thing:
extern "C"{
#include "A.h"
#include "B.h"
}
causes of course name conflict. What can I do to avoid this conflct, and have the robust code? Would such solution help:
A_Wrapper.h: //c++
extern "C"{
#include "A.h"
}
void WrapF_A(int x)
{
F(x);
}
B_Wrapper.h: //C++
extern "C"{
#include "B.h"
}
void WrapF_B(int x)
{
F(x);
}
and then in the program:
#include A_Wrapper.h
#include B_Wrapper.h
Modyfing each file in that project would be rather impossible as it cosists of hundreds of files, and i would probably damage some code rather. Is there a way to make an include file seen only in some part of the program?
EDIT:
So I created a simple project illustrating the problem, and tried to apply the hints given by doctorlove. However still multiple definition of F error occurs. What should I change? Project files:
A.h:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
int F(int x);
#endif // A_H_INCLUDED
A.c
#include "A.h"
int F(int x)
{
return x*x;
}
AWrapper.h:
#ifndef AWRAPPER_H_INCLUDED
#define AWRAPPER_H_INCLUDED
int AF(int x);
#endif // AWRAPPER_H_INCLUDED
AW.cpp:
#include "AWrapper.h"
extern "C"{
#include "A.h"
}
int AF(int x)
{
return F(x);
}
B.h:
#ifndef B_H_INCLUDED
#define B_H_INCLUDED
int F(int x);
#endif // B_H_INCLUDED
B.c:
#include "B.h"
int F(int x)
{
return -x*x;
}
BWrapper.h:
#ifndef BWRAPPER_H_INCLUDED
#define BWRAPPER_H_INCLUDED
int BF(int x);
#endif // BWRAPPER_H_INCLUDED
BW.cpp:
#include "BWrapper.h"
extern "C"{
#include "B.h"
}
int BF(int x)
{
return F(x);
}
Go with your wrapper idea, but write a facade (see also here) that exposes what you need from A, and what you need from B not all the functions in there.
You will end up with something like
//header Wrap_A.h
#ifndef WRAP_A_INCLUDED
#define WRAP_A_INCLUDED
//for some input Data left as an exercise for the reader...
double solve_with_A(Data data);
#endif
//header Wrap_B.h
#ifndef WRAP_B_INCLUDED
#define WRAP_B_INCLUDED
//for some input Data...
double solve_with_B(Data data);
#endif
Then make two cpp files that include all the conflicting headers files, those from A in A.cpp and those from B in B.cpp, so the conflicts don't happen. The solve_with_A and solve_with_B functions will then call all the things they need without without leaking them to the whole program and causing conflicts.
You might have to give some thought to what Data will actually be. You could define your own types, one for A and one for B. Just avoid exposing the implementation details in your wrapping/facade headers.
If headers are causing you pain, firewall them off in the naughty corner.
EDIT
Given you have two functions, F, if you put all the sources into one project the linker should and will complain it can see both. Instead, you need to make two static libraries, and just expose the wrapped version to your main project.
Thank you for looking at this post. I am trying to patch up a network block device driver. If you need to see the sources they are at http : / / code.ximeta.com.
I noticed that lock_kernel() seems deprecated as of linux 2.6.37. I read "The new way of ioctl()" and found that device drivers now should perform a specific lock before operating.
So I would like some advice replacing this if possible.
I have found two sections in the current code that I think are related, in the block folder section.
Source
block->io.c
->ctrldev.c
I put snippets from each for your consideration.
io.c contains one call to lock_kernel:
NDAS_SAL_API xbool sal_file_get_size(sal_file file, xuint64* size)
{
definitions and declarations etc..
lock_kernel();
#ifdef HAVE_UNLOCKED_IOCTL
if (filp->f_op->unlocked_ioctl) {
some small statements
error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size);
actions if error or not etc.
}
#endif
unlock_kernel();
return ret;
}
And ctrldev.c contains the main io function:
#include <linux/spinlock.h> // spinklock_t
#include <linux/semaphore.h> // struct semaphore
#include <asm/atomic.h> // atomic
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/ide.h>
#include <linux/smp_lock.h>
#include <linux/time.h>
......
int ndas_ctrldev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
lots of operations and functions.
return result;
}
Later ndas_ctrldev_ioctl function is set as the former .ioctl.
static struct file_operations ndasctrl_fops = {
.write = ndas_ctrldev_write,
.read = ndas_ctrldev_read,
.open = ndas_ctrldev_open,
.release = ndas_ctrldev_release,
.ioctl = ndas_ctrldev_ioctl,
};
Now I want to convert this to avoid using lock_kernel();
According to my understanding I will modified the former sections as below:
NDAS_SAL_API xbool sal_file_get_size(sal_file file, xuint64* size)
{
definitions and declarations etc..
#ifndef HAVE_UNLOCKED_IOCTL
lock_kernel();
#endif
#ifdef HAVE_UNLOCKED_IOCTL
if (filp->f_op->unlocked_ioctl) {
some small statements
error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size);
actions if error or not etc.
}
#endif
#ifndef HAVE_UNLOCKED_IOCTL
unlock_kernel();
#endif
return ret;
}
#ifdef HAVE_UNLOCKED_IOCTL
long ndas_ctrldev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
#else
int ndas_ctrldev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
#endif
{
#ifdef HAVE_UNLOCKED_IOCTL
! add some sort of lock here !
#endif
lots of operations and functions.
#ifdef HAVE_UNLOCKED_IOCTL
! add unlock statement here !
#endif
return result;
}
static struct file_operations ndasctrl_fops = {
.write = ndas_ctrldev_write,
.read = ndas_ctrldev_read,
.open = ndas_ctrldev_open,
.release = ndas_ctrldev_release,
#ifdef HAVE_UNLOCKED_IOCTL
.unlocked_ioctl = ndas_ctrldev_ioctl,
#else
.ioctl = ndas_ctrldev_ioctl,
#endif
};
So, I would ask the following advice.
Does this look like the right
proceedure?
Do I understand correct to move the
lock into the io function?
Based on the includes in crtrldev.c, can you
recommend any lock off the top of
your head? (I tried to research some
other drivers dealing with filp and
lock_kernel, but I am too much a
noob to find the answer right away.)
The Big Kernel Lock (BKL) is more than deprecated - as of 2.6.39, it does not exist anymore.
The way the lock_kernel() conversion was done was to replace it by per-driver mutexes. If the driver is simple enough, you can simply create a mutex for the driver, and replace all uses of lock_kernel() and unlock_kernel() by the mutex lock/unlock calls. Note, however, that some functions used to be called with the BKL (the lock lock_kernel() used to lock) held; you will have to add lock/unlock calls to these functions too.
This will not work if the driver could acquire the BKL recursively; if that is the case, you would have to track it yourself to avoid deadlocks (this was done in the conversion of reiserfs, which depended somewhat heavily both in the recursive BKL behavior and in the fact that it was dropped when sleeping).
The next step after the conversion to a per-driver mutex would be to change it to use a per-device mutex instead of a per-driver mutex.
Here is the solution.
#if HAVE_UNLOCKED_IOCTL
#include <linux/mutex.h>
#else
#include <linux/smp_lock.h>
#endif
.
.
.
#if HAVE_UNLOCKED_IOCTL
mutex_lock(&fs_mutex);
#else
lock_kernel();
#endif
This only shows replacing the lock call. The other parts worked out as I guessed in the question part above concerning unlocked_ioctl. Thanks for checking and for helping.