Pebble C TupletCString compile error - pebble-watch

I have an issue compiling my pebble watchapp. I am trying to send strings to the Pebbl eJS script on the phone lihe this:
Tuplet password_tuple = TupletCString(PASSWORD_KEY, password_str);
Tuplet email_tuple = TupletCString(EMAIL_KEY, email_str);
The compiler error is: (they both error out like this, this is just one of the lines of output below)
./src/app_test.c:84:25: error: the address of 'email_str' will always evaluate as 'true' [-Werror=address]
email_str and password_str are defined at the top of the program, like this:
static char email_str[30];
static char password_str[30];
#define PASSWORD_PKEY (int32_t)21
#define EMAIL_PKEY (int32_t)20
Does anyone notice anything wrong with this?

#ismail-badawi answer is very correct.
Pebble now recommends that you use dict_write_cstring.
dict_write_cstring(&iter, SOME_STRING_KEY, string);

Well it's certainly not obvious, but it turns out it's because TupletCString is a macro, and it'll expand to an expression that contains email_str ? strlen(email_str) + 1 : 0 as a subexpression, and this is what causes the error, because email_str can't be null and so the comparison isn't doing anything.
I found this thread on the Pebble forums with an explanation. The suggested fix is to define your own macro that doesn't have a conditional, e.g.
#define MyTupletCString(_key, _cstring) \
((const Tuplet) { .type = TUPLE_CSTRING, .key = _key, .cstring = { .data = _cstring, .length = strlen(_cstring) + 1 }})

Related

Error with Condor: "$INT() macro: 50+ $((0/41)) does not evaluate to an integer!"

I want to run several jobs with Condor, my executable take as an argument b such that: b1=50+ $(($(Process)/41)), where $(())stands for the quotient of $(Process) divided by 41. b is defined in quotient.sh. Here is my submit file:
# Unix submit description file
include : PATH/quotient.sh
executable = PATH/script_test.sh
arguments = $(b) $(Process)
log = fit_it_data_$INT(b)_$(Process).log
output = outfile_fit_$INT(b)_$(Process).txt
error = errors_fit_$INT(b)_$(Process).txt
transfer_input_files = PATH
should_transfer_files = Yes
when_to_transfer_output = ON_EXIT
queue 81
However I am getting the error Submitting job(s)ERROR at Queue statement on Line 13: $INT() macro: 50+ $((0/41)) does not evaluate to an integer!. I don't understand why it complains that is does not evaluate to an integer, since b should be equal to 50 here...
Any idea how to fix that issue?
b1=50+ $(($(Process)/41))
I think you have an extra "$" in there. Try this:
b1=50+ ($(Process)/41)

AENUM creating class bodies dynamically causes pylint warning

I cannot explain why I get a pylint "<class 'AttributeError'>: 'For' object has no attribute 'targets'" warning when I create enum entries dynamically.
I cannot see any reason for the the warning in my code.
from aenum import IntEnum
class Commands(IntEnum):
_ignore_ = 'Commands index'
_init_ = 'value string'
BEL = 0x07, 'Bell'
Commands = vars()
for index in range(4):
Commands[f'DC{index + 1}'] = 0x11 + index, f'Device Control {index + 1}'
for command in Commands:
print(f"0x{command.value:02X} is {command.string}")
The code works fine but I do NOT expect a warning!
The code is OK the bug was within the toolchain:
https://github.com/PyCQA/pylint/issues/2719

Meaning of yywrap() in flex

What does this instructions mean in flex (lex) :
#define yywrap() 1
and this [ \t]+$
i find it in the code below:
(%%
[ \t]+ putchar('_');
[ \t]+%
%%
input "hello world"
output "hello_world"
)
According to The Lex & Yacc Page :
When the scanner receives an end-of-file indication from YY_INPUT, it then checks the yywrap() function. If yywrap() returns false (zero), then it is assumed that the function has gone ahead and set up yyin to point to another input file, and scanning continues. If it returns true (non-zero), then the scanner terminates, returning 0 to its caller. Note that in either case, the start condition remains unchanged; it does not revert to INITIAL.
The #define is used to simplify building the program (so that no -ll linkage option is needed).
Further reading:
What are lex and yacc?
Routines to reprocess input
6. How do Lex and YACC work internally (Lex and YACC primer/HOWTO)

CLR IL-significance of square bracket on .locals init

I am trying to generate a dynamic assembly using Reflection & Emit in .NET. I am getting an error, "Common Language Runtime detected an invalid program." I created another program which has the functionality I want using hard-coded types. The functionality I am trying to write will ultimately use dynamic types, but I can use ILDasm to see the IL I need to generate. I am comparing the IL I am generating with the IL which the compiler generates. In the .locals init declaration of one method I see there is an extra item in the compiler-generated code,
compiler-generated:
.locals init ([0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
[1] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0001)
mine:
.locals init (class [System.Core]System.Linq.Expressions.ParameterExpression V_0,
class [System.Core]System.Linq.Expressions.ParameterExpression[] V_1)
I don't understand the significance of the "[0]" and "[1]" in the compiler-generated code. Can anyone tell me what it means?
As a more general question, I can follow most ILDasm output without too much trouble. But every so often I run across a problematic expression. For instance, in this line from ILDasm
callvirt instance class [EntityFramework]System.Data.Entity.ModelConfiguration.EntityTypeConfiguration`1<!!0> [EntityFramework]System.Data.Entity.DbModelBuilder::Entity<class DynamicEdmxTrial.HardFooAsset>()
the "!!0" probably refers to the generic type of the Entity<>, but I don't know for sure, and I wonder if there is a key to ILDasm output that would explain its more obscure output to me.
The specification is freely available here. It takes a little getting used to, but most details are easily found once you figure out the structure.
!! is listed in II.7.1 Types:
Type ::= | Description | Clause
‘!’ Int32 | Generic parameter in a type definition, | §II.9.1
| accessed by index from 0 |
| ‘!!’ Int32 | Generic parameter in a method | §II.9.2
| definition, accessed by index from 0 |
...
In other words, inside a method that C# would call f<T, U>(), !!0 would be T, and !!1 would be U.
However, the [0] is a good question. The spec does not seem to address it. The .locals directive is described in II.15.4.1.3 The .locals directive, which lists the syntax as
MethodBodyItem ::= ...
| .locals [ init ] ‘(’ LocalsSignature ‘)’
LocalsSignature ::= Local [ ‘,’ Local ]*
Local ::= Type [ Id ]
There is nothing that seems to allow [0] there unless it is part of a Type, and Type does not allow anything starting with [ either. My guess is that this is an undocumented peculiarity specific to Microsoft's implementation, intended to help the human reader see that location 0 is local variable CS$0$0000, for when the generated instructions access local variables by index.
Experimenting with ILAsm shows that this is exactly what it means. Taking a simple C# program:
static class Program {
static void Main() {
int i = 0, j = 1;
}
}
and compiling and then disassembling it (csc test.cs && ildasm /text test.exe >test.il) shows:
....
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldc.i4.1
IL_0004: stloc.1
IL_0005: ret
....
Modifying the .locals to
.locals init ([0] int32 V_0, [0] int32 V_1)
gives a useful warning message:
test.il(41) : warning : Local var slot 0 is in use
And indeed, declaring variables of different types, then reordering them using [2], [1], [0], assembling and immediately disassembling the result, shows that the variables got reordered.

Clang does not compile a g++ project

When trying to compile a g++ project with the clang compiler, there is a strange error showing up.
Here is the snippet of the source file:
std::set<TTransportNetworkId> l_transportNetworkIds;
SelectionResultContainer l_searchResult = p_repo.rootMoc() / LnAny("LNBTS") / LnAny("LNMME");
BOOST_FOREACH(const SelectionResult & l_lnmmeSR, l_searchResult)
{
const MoLnmme & l_lnmme = l_lnmmeSR;
l_transportNetworkIds.insert(*l_lnmme.transportNwId);
}
The error message is:
conditional expression is ambiguous; 'rvalue_probe<Rrom::DataRep::SelectionResultContainer>' can be converted to 'Rrom::DataRep::SelectionResultContainer' and vice versa
BOOST_FOREACH(const SelectionResult & l_lnmmeSR, l_searchResult)
Conditions are:
The file compiles fine with gcc_4.3.2
clang in version 3.2 throws the above error
Already tried to include the latest boost library which results in the same error
My guess is that clang handles rvalue conditions differently than this gcc version does.
clang is supposed to be a drop-in-replacement for gcc, so how can one get rid of this error without touching the source file?
Are there any options in clang which somehow disables these kind of errors?!
UPDATE:
I could create an example source file, which you can reproduce for yourself:
#include <vector>
#include <boost/foreach.hpp>
class A : public std::vector<int>
{
public:
template <class T>
operator const T &() const;
};
void foo(){
A colA;
int b = 1;
BOOST_FOREACH(b, colA)
{
;
}
}
When compiled with clang 3.2 the above error is raised, with some additional insights to where exactly the error occurs:
error: conditional expression is ambiguous; 'rvalue_probe<A>' can be converted to 'A' and vice versa BOOST_FOREACH(b, colA)
expanded from macro 'BOOST_FOREACH' f (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL))
expanded from macro 'BOOST_FOREACH_CONTAIN' BOOST_FOREACH_EVALUATE(COL)
expanded from macro 'BOOST_FOREACH_EVALUATE' (true ? boost::foreach_detail_::make_probe((COL), BOOST_FOREACH_ID(_foreach_is_rvalue)) : (COL))
This code is compiled without errors with gcc_4.7.2.
Any ideas why the two compilers behave differently?
I found the solution in this document, see http://www.boost.org/doc/libs/1_43_0/boost/foreach.hpp
Snippet:
// Some compilers do not correctly implement the lvalue/rvalue conversion
// rules of the ternary conditional operator.
# if defined(BOOST_FOREACH_NO_RVALUE_DETECTION)
So, when providing a -DBOOST_FOREACH_NO_RVALUE_DETECTION definition option to clang, the error disappears.
Still the question remains whether gcc or clang is right or wrong on this point.

Resources