Is This Response from the Compiler Valid

Is this response from the compiler valid?

Add a space after the =. (=[ looks too sad to be an operator.) It's probably seeing =value as a use of a (possible, but not implemented) prefix operator.

Swift isn't entirely whitespace-agnostic like C... in particular, it uses whitespace to distinguish prefix from postfix operators (because ++i++ in C is a grammar oddity). But it's not ridiculously strict about whitespace like Python either.

Why does != 0 cause a compiler error

This is probably due to the lack of whitespace around your != operator - Swift is quite fussy about whitespace, and interprets operators differently depending on their surrounding whitespace.

The language specification describes the various rules, although it is not particularly obvious from these that b!=0 should be invalid.

So you probably need to say b != 0 rather than b!=0

See also: Is this response from the compiler valid?

Swift: '==' is not a prefix unary operator

Try to add space after '=='.

Instead of :

if(result =="") {

try:

if(result == "") {

Is Type(::x); valid?

As far as I can tell this is covered by draft C++ standard section 8.3 Meaning of declarators paragraph 6 which says (emphasis mine going forward):

In a declaration T D where D has the form

( D1 )

the type of the contained declarator-id is the same as that of the contained declarator-id in
the declaration

T D1

Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex
declarators.

so:

int(::x);

is equivalent to:

int ::x ;

which is clearly not valid, and this produces the same error as well. So gcc 4.9 is not correct here but since this looks fixed in the gcc 4.8.3 which was released later I would expect this to be fixed in later releases of 4.9 as well. Although I don't see any obvious matches for this issue in the gcc 4.8.3 bugs fixed list but they don't claim it is a complete list.

The second case is a functional explicit type conversion which is covered in section 5.2.3 Explicit type conversion (functional notation) which says:

A simple-type-specifier (7.1.6.2) or typename-specifier (14.6)
followed by a parenthesized expression-list constructs a value of the
specified type given the expression list. If the expression list is a
single expression, the type conversion expression is equivalent (in
definedness, and if defined in meaning) to the corresponding cast
expression (5.4).[...]

This is unambiguous since ::x + 2 is an expression.

The section that covers when a statement is considered a declaration or a expression is 6.8 Ambiguity resolution which says:

There is an ambiguity in the grammar involving expression-statements
and declarations: An expressionstatement with a function-style
explicit type conversion (5.2.3) as its leftmost subexpression can be
indistinguishable from a declaration where the first declarator starts
with a (. In those cases the statement is a declaration. [ Note: To
disambiguate, the whole statement might have to be examined to
determine if it is an expression-statement or a declaration. This
disambiguates many examples.

and provides the following examples:

T(a)->m = 7; // expression-statement
T(a)++; // expression-statement
T(a,5)<<c; // expression-statement
T(*d)(int); // declaration
T(e)[5]; // declaration
T(f) = { 1, 2 }; // declaration
T(*g)(double(3)); // declaration

Note: without the () then T ::D is a qualified-id in the case of T being a class, that is a covered in the grammar of 5.1 Primary expressions.

Update

Filed a gcc bug report.

gcc's response is that:

Current G++ and EDG both treat it as the valid expression (int)::x

Since this response implies clang is incorrect(I don't agree though), I filed a clang bug report and older bug report looks similar and seems to disagree with the gcc response.

Update 2

In response to the clang bug report Richard Smith agrees this should be treated as a declaration and says:

That does not imply clang is incorrect; in fact, Clang is correct
here, as far as I can see. (I've also sent a bug report to EDG.)

That said, we should give a proper 'you hit a vexing parse, here's how
to disambiguate' error in this case.

Update 3

gcc confirms it is a bug.

Why std::is_functionT is causing compilation error?

The issue is here:

template <class InputIterator, class Function>
Function my_for_each(InputIterator first, InputIterator last, Function f)

invoked via:

my_for_each(vec_x.begin(), vec_x.end(), display);

This deduces Function (of my_for_each) to be a function pointer; for

void  display(int& val)

the deduced type is void(*)(int&). The type trait std::is_function however checks if the passed type is a function type, not a function pointer type.


One solution is to remove the pointer:

template<typename T>
constexpr bool Is_valid_function(T& a) {
return std::is_function<typename std::remove_pointer<T>::type>::value;
}

But, as clang++ reveals, this still isn't sufficient:

template<typename T>
void check_valid_function(T& a) {
static_assert(Is_valid_function(a), "Not The Valid Function");
}

a as a function parameter (even if check_valid_function was constexpr!) is not a compile-time constant, therefore it may not appear in a constant expression (inside the function body). Hence, Is_valid_function(a) may not appear as the check for the static_assert. It might be possible to use something similar to declval, e.g.

static_assert(Is_valid_function( declval<T&>() ), "Not The Valid Function");

but unfortunately, declval is not constexpr, and I don't know how to write a constexpr version. So, you could pass a pointer instead:

static_assert(Is_valid_function(static_cast<T*>(nullptr)),
"Not a valid function");

For this, you need to rewrite Is_valid_function as follows:

template<typename T>
constexpr bool Is_valid_function(T*) {
return std::is_function<typename std::remove_pointer<T>::type>::value;
}

Note: the passed argument here is a pointer to a pointer to a function, but the parameter T* deduced T to be a pointer to a function, as before (hence the change in the signature). You might want to reflect that in the function name, if you choose this solution.


Other issues:

  1. Relying on ADL for Standard Library algorithms

    return for_each(first, last, f) ;

    As far as I can see, this relies on ADL. But the iterators (and the function) are not required to be in namespace std (even for vector::iterator etc.), so you shouldn't rely on ADL:

    return std::for_each(first, last, f);
  2. Use of non-const refs for functions that don't need to modify their arguments, e.g.

    constexpr   bool  Is_valid_function(T& a)

    If you don't need to modify an argument, you should either pass it by value or by const reference, e.g.

    constexpr   bool  Is_valid_function(T const& a)
  3. "Wrong check" If this code is just for educational purposes, this isn't an issue. However, the check if the passed argument is of a function type is the "wrong check" when trying to check if the argument valid for a Standard Library algorithm. You should rather check whether f(*first) is well-formed. This allows for function objects and checks if the argument type is "valid".

Why is n+++n valid while n++++n is not?

The file is tokenized (transformed into sequence of tokens) first with the maximal munch rule - always get longest possible valid token. Your text is transformed to following sequence:

n ++ ++ n

And this is not valid expression.

From JLS §3.2:

3.2. Lexical Translations


A raw Unicode character stream is translated into a sequence of tokens, using the following three
lexical translation steps, which are applied in turn:

  1. A translation of Unicode escapes (§3.3) in the raw stream of Unicode
    characters to the corresponding Unicode character. A Unicode escape
    of the form \uxxxx, where xxxx is a hexadecimal value, represents
    the UTF-16 code unit whose encoding is xxxx. This translation step
    allows any program to be expressed using only ASCII characters.

  2. A translation of the Unicode stream resulting from step 1 into a stream of input characters and line terminators (§3.4).

  3. A translation of the stream of input characters and line terminators resulting from step 2 into a sequence of input elements
    (§3.5) which, after white space (§3.6) and comments (§3.7) are
    discarded, comprise the tokens (§3.5) that are the terminal symbols
    of the syntactic grammar (§2.3).


The longest possible translation is used at each step, even if the result does not ultimately make a correct program while another
lexical translation would.

(Thus, the input characters a--b are tokenized (§3.5) as a, --, b,
which is not part of any grammatically correct program, even though
the tokenization a, -, -, b could be part of a grammatically correct
program.)

unable to compile a code when converted into a function

i was able to solve it but now I am left with more questions than answers. Would appreciate if someone could explain the behaviour to me.

I was using the following httpOptions object

const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),

withCredentials: true,
observe: 'response' as 'response',

};

as was using it as follows in some places in the code.

 return this.http.post(this.SIGNUP_USER_URL,body,httpOptions)

This worked.

Then I thought of changing the http.post into a function sendMessage (as explained in the question) and replaced it in only once place (remember I am using this.http.post in several places so wanted to try it at one place to begin with). I noticed that using httpOptions made post return Observable<ArrayBuffer>.

Doubt 1 - why?

Then I changed httpOptions to

const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),

withCredentials: true,
observe: 'response' as 'response',
responseType:'json'
};

It started giving me errors at places where I am using http.post directly (without sendMessage. The error was

ERROR in src/app/web-to-backend-interface.service.ts(81,71): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
Types of property 'observe' are incompatible.
Type '"response"' is not assignable to type '"body"'.
src/app/web-to-backend-interface.service.ts(112,52): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
Types of property 'observe' are incompatible.
Type '"response"' is not assignable to type '"body"'.
src/app/web-to-backend-interface.service.ts(196,73): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
src/app/web-to-backend-interface.service.ts(216,72): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
src/app/web-to-backend-interface.service.ts(251,54): error TS2345: Argument of type '{ headers: HttpHeaders; withCredentials: boolean; observe: "response"; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
src/app/web-to-backend-interface.service.ts(291,9): error TS2322: Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<HttpEvent<any>>'.
Type 'ArrayBuffer' is not assignable to type 'HttpEvent<any>'.
Type 'ArrayBuffer' is not assignable to type 'HttpUserEvent<any>'.
Property 'type' is missing in type 'ArrayBuffer'.

So I removed responseType:'json' from httpOptions and added an explicit object in this.http.post in my sendMessage which worked!

private sendMessage(url:string, body:any,httpOptions){
...
let observable:Observable<HttpEvent<any>> = this.http.post(url,body,{
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
withCredentials: true,
observe: 'events',
responseType: 'json'
})
...
}

there seem to be relationship between observe and responseType. Eg observe=body and responseType=text means that post should observe (look in) the body, interpret it as text and return Observable. But I wonder why I just couldn't change httpOptions

Code is valid in Eclipse, cannot be compiled by the JDK

javac 1.7.0_04 compiles the source without error, so I'd suggest this is a bug in javac 1.6.



Related Topics



Leave a reply



Submit