How do GCC process macros when one reference the other - macros

//foo.h
#define X TEST-9
#define TEST 10
//foo.c
#include<stdio.h>
#include"foo.h"
int main(void)
{
int a = X;
printf("%d\n", a);
}
when I run :
gcc -o foo foo.c -Wall -Wextra
there is no outout,then run:
./foo
result is: 1
my queston is:
X references TEST,but TEST is defined after X,why can X expansion correctly

X references TEST,but TEST is defined after X,why can X expansion correctly
Expansion happens upon use. When X is used at line int a = X, #define TEST is visible.
It's string replacement. X is expanded to the string TEST-9 then that string is rescanned for further replacements, TEST is found, and then TEST is replaced by 10, resulting in the string 10-9.

Related

Doxygen remove Macro Definition Documentation

I use Doxygen version 1.9.3.
I have a c file :
#define l 20;
#define n 30;
#define k 40;
static void func1(int a, int b)
{
printf("a %d",a);
}
int func2(int x )
{
return x;
}
long func3(char c)
{
long temp = 0;
return temp;
}
The file has 3 #define, after running Doxygen my output looks like this:
Is there a way to remove the Macro Definition Documentation section? I just want the Macro section.
doxygen -x Doxyfile output:

How can I convert the input operator (+,-) to math in C

Assume that the given input are 5,+,5 in C.
ex)
5
+
5
And I would like to get the answer 10.
I thought code like the below.
#include
using namespace std;
int main(){
char a,b,symbol;
cin >> a >> symbol >> b;
printf("%d", (a-'0') symbol (b-'0'));
return 0;
}
Expected value is 10. However, I got an error in symbol
How would I get the solution?
There are multiple things that I noticed:
First, you are printing integer, but a and b are both chars.
Knowing that there are only a few symbols that you can use, maybe a switch case would be more appropriate?
int main(){
int a, b;
char symbol;
switch(symbol){
case('-'): print("%d", a - b);
case('+'): print("%d", a + b);
case('*'): print("%d", a * b);
case('/'): print("%d", a / b);
case('%'): print("%d", a % b);
default : print("Not a known symbol");
}
Second: Why are you substracting a from the character 0?

In mex file, I can't overwrite scalar through the pointer in matlab2016a, although I can overwrite the scalar in 2013a and also the array in 2016a

[environment]
OS: OSX10.11 and maxOS Sierra(10.12)
MATLAB: matlab2013a and matlab2016a
Xcode: xcode7 and xcode8
In my work, I must use the following mex file in the old package.
//destructiveMatrixWriteAtIndices.c
//------------------------------------------------------
#include <matrix.h> /* Matlab matrices */
#include <mex.h>
#include <stddef.h> /* NULL */
#define notDblMtx(it) (!mxIsNumeric(it) || !mxIsDouble(it) || mxIsSparse(it) || mxIsComplex(it))
void mexFunction(int nlhs, /* Num return vals on lhs */
mxArray *plhs[], /* Matrices on lhs */
int nrhs, /* Num args on rhs */
const mxArray *prhs[] /* Matrices on rhs */
)
{
double *mtx;
double *newValues;
double *doubleStartIndex;
int i, startIndex, size;
mxArray *arg;
if (nrhs != 3) mexErrMsgTxt("requires 3 arguments.");
/* ARG 1: MATRIX */
arg = prhs[0];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
mtx = mxGetPr(arg);
arg = prhs[1];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
newValues = mxGetPr(arg);
size = (int) mxGetM(arg) * mxGetN(arg);
arg = prhs[2];
if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
doubleStartIndex = mxGetPr(arg);
startIndex = (int) doubleStartIndex[0];
for (i=0; i<size; i++){
mtx[i+startIndex] = newValues[i];
}
return;
}
//------------------------------------------------------
This mex file is the function to overwrite the scalar and the part of matrix through the pointer.
e.g. in matlab2013a command window (scalar in matlab2013a)
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "3".
e.g. in matlab2013a and matlab2016a command window (matrix in matlab2013a and matlab2016a)
a = [1, 2];
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "[3, 2]".
e.g. in matlab2016a command window (scalar in matlab2016a)
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
and the variable "a" becomes "1"! Why?
I also used the lldb, and revealed the strange behavior of this code.
In matlab2013a and matlab2016a, when I run the following snippet.
a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);
The lldb revealed "*mtx = 3" at the end of the mex function in both matlab, but the mex function couldn't pass the result(*mtx = 3, or prhs[0] = 3) through the pointer in the only matlab2016a.
It's very strange behavior!
※I have understood that this mex function is very danger, but this mex function was used at some points in the package that I must use. Therefore, I must fix this mex file and make the package run in matlab2016a.
Please help me.
I'm pretty sure you're not meant to modify the input array in a mex function. More details here Does Matlab ever copy data passed to a mex function?. The "matlab" solution is probably to return the modified array as an output of the mex rather modifying in place.

No Symbols Loaded: libmex.pdb not loaded (throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH : C++ exception)

In order to create a MEX function and use it in my MATLAB code, like this:
[pow,index] = mx_minimum_power(A11,A12,A13,A22,A23,A33);
I've created the file mx_minimum_power.cpp and written the following code in it:
#include <math.h>
#include <complex>
#include "mex.h"
#include "matrix.h"
#include "cvm.h"
#include "blas.h"
#include "cfun.h"
using std::complex;
using namespace cvm;
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
const int arraysize = 62172;
const int matrixDimention = 3;
float *inMatrixA11 = (float *)mxGetPr(prhs[0]);
complex<float> *inMatrixA12 = (complex<float> *)mxGetPr(prhs[1]);
complex<float> *inMatrixA13 = (complex<float> *)mxGetPr(prhs[2]);
float *inMatrixA22 = (float *)mxGetPr(prhs[3]);
complex<float> *inMatrixA23 = (complex<float> *)mxGetPr(prhs[4]);
float *inMatrixA33 = (float *)mxGetPr(prhs[5]);
basic_schmatrix< float, complex<float> > A(matrixDimention);
int i = 0;
for (i = 0; i < arraysize; i++)
{
A.set(1, 1, inMatrixA11[i]);
A.set(1, 2, inMatrixA12[i]);
A.set(1, 3, inMatrixA13[i]);
A.set(2, 2, inMatrixA22[i]);
A.set(2, 3, inMatrixA23[i]);
A.set(3, 3, inMatrixA33[i]);
}
}
And then in order to be able to debug the code, I've created the mx_minimum_power.pdb and mx_minimum_power.mexw64 files, using the following code in the Matlab Command Window:
mex -g mx_minimum_power.cpp cvm_em64t_debug.lib
The files blas.h, cfun.h, cvm.h and cvm_em64t_debug.lib are in the same directory as mx_minimum_power.cpp.
They are the headers and library files of the CVM Class Library.
Then I've attached MATLAB.exe to Visual Studio 2013, using the way explained here.
and have set a breakpoint at line40:
When I run my MATLAB code, there's no error until the specified line.
But if I click on the Step Over button, I'll encounter the following message:
With the following information added to the Output:
First-chance exception at 0x000007FEFCAE9E5D in MATLAB.exe: Microsoft C++ exception: cvm::cvmexception at memory location 0x0000000004022570.
> throw_segv_longjmp_seh_filter()
throw_segv_longjmp_seh_filter(): C++ exception
< throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH
Can you suggest me why libmex.pdb is needed at that line and how should I solve the issue?
If I stop debugging, I'll get the following information in MATLAB Command Window:
Unexpected Standard exception from MEX file.
What() is:First index value 0 is out of [1,4) range
Right before pressing the step over button, we have the following values for A11[0],A12[0],A13[0],A22[0],A23[0],A33[0]:
that are just right as my expectations, according to what MATLAB passes to the MEX function:
Maybe the problem is because of wrong allocation for matrix A, it is as follows just before pressing the step over button.
The problem occurs because we have the following code in lines 48 to 53 of the cvm.h file:
// 5.7 0-based indexing
#if defined (CVM_ZERO_BASED)
# define CVM0 TINT_ZERO //!< Index base, 1 by default or 0 when \c CVM_ZERO_BASED is defined
#else
# define CVM0 TINT_ONE //!< Index base, 1 by default or 0 when \c CVM_ZERO_BASED is defined
#endif
That makes CVM0 = 1 by default. So if we press the Step Into(F11) button at the specified line two times, we will get into line 34883 of the file cvm.h:
basic_schmatrix& set(tint nRow, tint nCol, TC c) throw(cvmexception)
{
this->_set_at(nRow - CVM0, nCol - CVM0, c);
return *this;
}
Press Step Into(F11) at line this->_set_at(nRow - CVM0, nCol - CVM0, c); and you'll go to the definition of the function _set_at:
// sets both elements to keep matrix hermitian, checks ranges
// zero based
void _set_at(tint nRow, tint nCol, TC val) throw(cvmexception)
{
_check_lt_ge(CVM_OUTOFRANGE_LTGE1, nRow, CVM0, this->msize() + CVM0);
_check_lt_ge(CVM_OUTOFRANGE_LTGE2, nCol, CVM0, this->nsize() + CVM0);
if (nRow == nCol && _abs(val.imag()) > basic_cvmMachMin<TR>()) { // only reals on main diagonal
throw cvmexception(CVM_BREAKS_HERMITIANITY, "real number");
}
this->get()[this->ld() * nCol + nRow] = val;
if (nRow != nCol) {
this->get()[this->ld() * nRow + nCol] = _conjugate(val);
}
}
pressing Step Over(F10) button,you'll get the result:
so in order to get nRow=1 and nCol=1 and not nRow=0 and nCol=0, which is out of the range [1,4), you should write that line of code as:
A.set(2, 2, inMatrixA11[i]);

error during token replacement in macros

I wrote this small program expecting that the values will be placed and it would see the output but i get an error:
D:\C Programming\token-pasting.c||In function 'main':|
D:\C Programming\token-pasting.c|6|error: 'Hell23' undeclared (first use in this function)|
D:\C Programming\token-pasting.c|6|note: each undeclared identifier is reported only once for each function it appears in|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|
#include <stdio.h>
#define swap(front, back) front##back
main()
{
swap(Hell, 23) ;
return 0;
}
There's a million ways to print "hell21", still need context. And ditch your "swap" macro...
char *str = "hell";
int x = 21;
printf("%s%d", str, x);
%s says to replace that part of printf with a string array, %d says to replace that part of printf with an integer.