How to define multiple c flags in ios? - ios

In Build settings, at custom compiler Flags, how can i declare two other C flags names?
For example:
Other C Flags: -DEXAMPLE
I tried:
Other C Flags: -DEXAMPLE, -DEXAMPLE2
-DEXAMPLE2 is not working. How can i declare multiple C Flags?

Drop the comma, each -D is its own argument to the compiler:
-DEXAMPLE -DEXAMPLE2

Related

How does clang check redefinitions?

I'm new to Clang, and trying to write some clang-tidy checks. I want to find something that works as a "variable table", to check if some names are well-formed.
My intuition is like this:
To write redefinition code will sometimes cause an error, which is thrown out by Clang's diagnostics. like:
int main(){
int x;
int x; // error: redefinition
return 0;
}
From my perspective, clang may keep a dynamic variable table to check whether a new definition is compatible/overloading/error.
I tried to dive into clang source code and explored something:
Identifiertable, is kept by preprocessor, which marks all the identifiers, but does not do the semantic legal checking.
DeclContext, which seems to be an interface for users to use, a product produced by semantic checking.
My question is :
How Clang do the legal checking?
Am I able to get the variable table(If there exists such kind of things)?
If I cannot get such things, how could I know which variables are reachable from a location?
Thanks for your suggestions!
TLDR; see Answers below.
Discussion
All of your questions are related to one term of C standard, identifier, in C99-6.2.1-p1:
An identifier can denote an object; a function; a tag or a member of a structure, union, or
enumeration; a typedef name; a label name; a macro name; or a macro parameter.
Each identifier has its own scope, one of the following, according to C99-6.2.1-p2:
For each different entity that an identifier designates, the identifier is visible (i.e., can be
used) only within a region of program text called its scope.
Since what you are interested in are the variables inside a function (i.e., int x), then it should then obtain a block scope.
There is an process called linkage for the identifiers in the same scope, according to C99-6.2.2-p2:
An identifier declared in different scopes or in the same scope more than once can be
made to refer to the same object or function by a process called linkage.
This is exactly the one that put a constraint that there should be only one identifier for one same object, or in your saying, definition legally checking. Therefore compiling the following codes
/* file_1.c */
int a = 123;
/* file_2.c */
int a = 456;
would cause an linkage error:
% clang file_*
...
ld: 1 duplicate symbol
clang: error: linker command failed with exit code 1
However, in your case, the identifiers are inside the same function body, which is more likely the following:
/* file.c */
int main(){
int b;
int b=1;
}
Here identifier b has a block scope, which shall have no linkage, according to C99-6.2.2-p6:
The following identifiers have no linkage: an identifier declared to be anything other than
an object or a function; an identifier declared to be a function parameter; a block scope
identifier for an object declared without the storage-class specifier extern.
Having no linkage means that we cannot apply the rules mentioned above to it, that is, it should not be related to a linkage error kind.
It is naturally considered it as an error of redefinition. But, while it is indeed defined in C++, which is called One Definition Rule, it is NOT in C.(check this or this for more details) There is no exact definition for dealing with those duplicate identifiers in a same block scope. Hence it is an implementation-defined behavior. This might be the reason why with clang, the resulting errors after compiling the above codes (file.c) differs from the ones by gcc, as shown below:
(note that the term 'with no linkage' by gcc)
# ---
# GCC (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04))
# ---
$ gcc file.c
file.c: In function ‘main’:
file.c:4:6: error: redeclaration of ‘b’ with no linkage
int b=1;
^
file.c:3:6: note: previous declaration of ‘b’ was here
int b;
^
# ---
# CLANG (Apple clang version 13.0.0 (clang-1300.0.29.3))
# ---
% clang file.c
file.c:4:6: error: redefinition of 'b'
int b;
^
file.c:3:6: note: previous definition is here
int b=1;
^
1 error generated.
Answers
With all things above, I think it suffices to answer your questions:
How clang perform the definition legally checking?
For global variables, either clang or gcc would follow the C standard rules, that is to say, they handle the so-called "redefinition errors" by the process called Linkage. For local variables, it is undefined behavior, or more precisely, implementation-defined behavior.
In fact, They both view the "redefinition" as an error. Although variable names inside a function body would be vanished after compiled (you can verify this in the assembly output), it is undoubtedly more natural and helpful for letting them be unique.
Am I able to get the variable table(If there exists such kind of things)?
Having not so much knowledge about clang internals, but according to the standards quoted above, along with an analysis of compiling, we can infer that IdentifierTable might not much fit your needs, since it exists in "preprocessing" stage, which is before "linking" stage. To take a look how clang compiler deals with duplicate variables (or more formally, symbols), and how to store them, you might want to check the whole project of lld, or in particular, SymbolTable.

GNU Assembler (Arm64). Parentheses in macro arguments references

I'm trying to find any information parentheses syntax for macro arguments in GNU Assembler. E.g. I have following code:
.macro do_block, enc, in, rounds, rk, rkp, i
eor \in\().16b, \in\().16b, v15.16b
...
(taken from here)
What does paretheses in \in\().16b mean? Where to find documentaion for this syntax?
Okay, I've found the answer. This is special syntax to escape macro-argument name.
From the documentation:
Note that since each of the macargs can be an identifier exactly as any other one permitted by the target architecture, there may be occasional problems if the target hand-crafts special meanings to certain characters when they occur in a special position. For example:
...
problems might occur with the period character (‘.’) which is often allowed inside opcode names (and hence identifier names). So for example constructing a macro to build an opcode from a base name and a length specifier like this:
.macro opcode base length
\base.\length
.endm
and invoking it as ‘opcode store l’ will not create a ‘store.l’ instruction but instead > generate some kind of error as the assembler tries to interpret the text \base.\length.
The string \() can be used to separate the end of a macro argument from the following text. eg:
.macro opcode base length
\base\().\length
.endm

Why does the nm tool output for the extern-only and defined-only options overlap?

I'll start by giving my understanding of the options:
extern-only: Show me only those symbols which are referenced by the binary but whose definitions (the code or variable) will be provided by another binary
defined-only: Show me only those symbols whose definitions are contained in the binary.
Here are my commands and their output:
$nm -defined-only GenerationOfNow | grep FIRAZeroingWeakContainer
000000010002c128 t -[FIRAZeroingWeakContainer .cxx_destruct]
000000010002c0fb t -[FIRAZeroingWeakContainer object]
000000010002c114 t -[FIRAZeroingWeakContainer setObject:]
000000010021a218 S _OBJC_CLASS_$_FIRAZeroingWeakContainer
00000001002177f8 s _OBJC_IVAR_$_FIRAZeroingWeakContainer._object
000000010021a1f0 S _OBJC_METACLASS_$_FIRAZeroingWeakContainer
$nm -extern-only GenerationOfNow | grep FIRAZeroingWeakContainer
000000010021a218 S _OBJC_CLASS_$_FIRAZeroingWeakContainer
000000010021a1f0 S _OBJC_METACLASS_$_FIRAZeroingWeakContainer
As you can see, the -extern-only output is a subset of the -defined-only output. Why? Perhaps my question should be: What is the meaning of those items which have a S in the second column?
You're confusing -extern-only with -undefined-only.
There are two concepts that are being mixed here:
extern vs. local (in C extern vs. static, "local" is sometimes also called "private")
defined vs. undefined
The former describes the availability of a symbol while the latter describes its origin. And yes, even the notion of a private undefined symbol exists, as per man nm:
Each symbol name is preceded by its value (blanks if undefined). [...] A lower case u in a dynamic shared library indicates a undefined reference to a private external in another module in the same library.
Now, when using -undefined-only you actually do get the complement of -undefined-only
bash$ nm test.dylib
0000000000000f60 T _derp
0000000000000f70 t _herp
U _printf
U dyld_stub_binder
bash$ nm -defined-only test.dylib
0000000000000f60 T _derp
0000000000000f70 t _herp
bash$ nm -undefined-only test.dylib
_printf
dyld_stub_binder
bash$ nm -extern-only test.dylib
0000000000000f60 T _derp
U _printf
U dyld_stub_binder
-extern-only does not seem to have a complementary flag however.

Expose a Fortran variable to C

I learned how to use C global variables in Fortran code, as given in the example below. But how to do it in a reverse direction, i.e., define (and initialize) a variable in Fortran and make it accessible to C?
/* C global variables */
int c_extern;
long myVariable;
!Fortran binding code
MODULE LINK_TO_C_VARS
USE ISO_C_BINDING
!Implicit label binding
!Bind variable C_EXTERN to c_extern
INTEGER(C_INT), BIND(C) :: C_EXTERN
!Explicit label binding
!Bind C2 to myVariable
INTEGER(C_LONG) :: C2
BIND(C, NAME='myVariable') :: C2
END MODULE LINK_TO_C_VARS
Follow-up:
Thanks to M.S.B.
I did some experiments. I put the C code in vars.c, the Fortran code in mod.f90.
gcc -c vars.c
nm vars.o
0000000000000004 C c_extern
0000000000000008 C myVariable
gfortran -c mod.f90
nm mod.o
0000000000000004 C c_extern
0000000000000008 C myVariable
'man nm' says: "C" -- The symbol is common. Common symbols are uninitialized data. When linking, multiple common symbols may appear with the same name. If the symbol is defined anywhere, the common symbols are treated as undefined references.
Then, I changed variables in vars.c to extern
<<vars-ext.c>>
extern int c_extern;
extern long myVariable;
gcc -c vars-ext.c and nm vars-ext.o
U c_extern
U myVariable
gfortran can successfully link mod.o with vars.o or vars-ext.o. It looks that the magic lies in the "C" kind symbols.

Ninja build in xText

I'm trying to define a grammar for ninja build with xtext.
There are three tricky points that I can't answer.
Indentations by tab:
How to handle indentations. A rule in a ninja build file might have several variable definitions with preceding tab spacing (similar to make files). This becomes a problem when the language has SL comments, ignores white-spaces and does indentation by tabs (python, make,...)
cflags = -g
rule cc
command = gcc $cflags -c $in -o $out
Cross referencing reserved set of variable names:
There exists a set of reserved variables. Auto-complete should be able to reference both the reserved and the user defined set of variables.
command = gcc $cflags -c $in -o $out
Autocompleting cross referenced variable names which aren't seperated with WS
org.eclipse.xtext.common.Terminals hides WS tokens. ID tokens are seperated by white spaces. But in ninja script (similar to make files) the parsing should be done with longest matching variable name.
some_var = some_value
command = $some_var.h
Any ideas are appreciated. Thanks.
Check out the Xtext 2.8.0 release: https://www.eclipse.org/Xtext/releasenotes.html
The Whitespace-Aware Languages section states:
Xtext 2.8 supports languages in which whitespace is used to specify
the structure, e.g. using indentation to delimit code blocks as in
Python. This is done through synthetic tokens defined in the grammar:
terminal BEGIN: 'synthetic:BEGIN';
terminal END: 'synthetic:END';
These tokens can be used like other terminals in grammar rules:
WhitespaceAwareBlock:
BEGIN
...
END;
The new example language Home Automation available in the Eclipse examples (File → New → Example → Xtext Examples) demonstrates this concept. It allows code like the following:
Rule 'Report error' when Heater.error then
var String report
do
Thread.sleep(500)
report = HeaterDiagnostic.readError
while (report == null)
println(report)
More details are found in the documentation.

Resources