Thursday, September 26, 2019

Rust and the C preprocessor.

I'm a long time C and C++ programmer.

And I enjoy using the C preprocessor also.

Trying out Rust.

But I must have those "tables", and the Rust macros are not good, so I must have the C preprocessor.

Cargo.toml:

[build-dependencies]
cc = "1.0"

build.rs:

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
extern crate cc;

fn main() {
 let out_dir = env::var("OUT_DIR").unwrap();
 let dest_path = Path::new(&out_dir).join("wasm_instructions.rs");
 let mut f = File::create(&dest_path).unwrap();

 let c = &mut cc::Build::new();
 c.flag("-I.").file("src/wasm_instructions.h");
    
 // Preprocess w/o line numbers
 // -EP for Visual C++
 // -E -P for gcc
 //
 // TODO Compiler detection.
 //
 // Nothing works, so remove line directives ourselves.

 for s in String::from_utf8(c.expand()).unwrap().lines() {
  let bytes = s.as_bytes();
  if bytes.len() > 0 && bytes [0] != b'#' {
   f.write(bytes).unwrap();
   f.write(b"\n").unwrap();
  }
 }
}




The .h file looks like this:


#ifdef FOO


FOO(...)
FOO(...)



#else

#undef FOO
#define FOO(...)
#include __FILE__



#undef FOO
#define FOO(...)
#include __FILE__

#endif

Tuesday, May 28, 2019

C++ disappointment? Member functions adding parameters?


This seems like such a basic thing:


int foo(int local, int context);​
struct A​
{​
    int context;​
    int foo (int local)​
    {​
        //return foo (local, context);​ // would be nice, but not legal
        return ::foo (local, context);​ // workaround
    }​
};​


And then wrap it in a namespace:

namespace n1​
{​
int foo(int local, int context);​
struct A​
{​
    int context;​
    int foo (int local)​
    {​
        return ::foo (local, context);​ // no longer correct
    }​
};​
}​


it seems to me there are two principles violated here:
  1. I shouldn't have to disambiguate in the first place. The lexical scopes should be merged. Too ambiguous?
2. If I have to disambiguate, code should not have to know what namespace it is in.
I should be able to wrap existing code in namespaces w/o breaking it.