I have the following module signature A:
module type A =
sig
type exp =
Int of int
| Var of string
end;;
which I am able to compile in order to get a.mli and a.cmi files. However, if I define B:
module type B =
sig
val compute : A.exp -> A.exp
end;;
running ocamlc -i b.ml produces the error Unbound type constructor A.exp. Why is that?
OCaml gives you an outer module for free, corresponding to each source file. So you are defining a module type named A.A. Note that it's a module type, not a module.
It's possible your a.ml (and a.mli if you like) should contain just the following:
type exp = Int of int | Var of string
Then you can refer to A.exp from your b.ml file.
Also, note that a.mli is a source file. If you have an a.mli file, you need to compile it to create a.cmi.
Related
While developing code for STM32 MCU, I'm placing some structures into custom memory section:
struct MyStruct structName;
__attribute__((__section__("my_section"))) __attribute__((__used__)) const struct MyStruct *const mystruct1 = &x
Linker generated additional symbols, __start_my_section_ and __stop_my_section_.
After compilation while debugging MCU, I see that __start_my_section_ contains a valid value, e.g. 0x20000468 but __stop_my_section_ is incorrect, equal to 0.
In the .map file, the __stop_my_section_ also contains a valid value:
0x20000470 __stop_my_section_ = .
What's wrong? I haven't added anything to linker script, linker automatically created that section and placed in bss.
Consider the simple C file:
int main()
{
int x = 0;
return x;
}
I'd like to extract a few things:
Ideally, all named things and their type. So I should get something like: int, main, function and int x variable or something like that
Extra points if the variable initialization is there as well
I'm sure that gcc does this internally, since that's an important compilation step, but I'm not sure if I can extract this information.
I'm also not strictly tied to gcc, so if another compiler does this I can consider it, but gcc is preferred.
I'm trying to assign the address that a base class smart pointer is pointing to to a raw pointer of a derived class. The size of data that the base class pointer is pointing to is the same of the derived class.
Directory is the derived class and FileData is the base class.
Here is where I initialize the derived class in main
Directory temp;
Directory * currentDir = &temp;
I then try to do the following conversion after some non-relevant code.
if (typeid(files[i]) == typeid(Directory))
{
*this = static_cast<Directory *>(&files[i]);
}
where files is the following in the body of the Directory class
std::vector<std::shared_ptr<FileData>> files
and *this is
Directory * currentDir
I get the following error from the static_cast line
invalid static_cast from type ‘__gnu_cxx::__alloc_traits<std::allocator<std::shared_ptr<FileData> >, std::shared_ptr<FileData> >::value_type*’ {aka ‘std::shared_ptr<FileData>*’} to type ‘Directory*’
I even tried to dynamic_cast instead
if (typeid(files[i]) == typeid(Directory))
{
*this = dynamic_cast<Directory *>(&files[i]);
}
But it says that FileData (base class) is not of polymorphic type
cannot dynamic_cast, (source type is not polymorphic)
Despite the deconstructor of FileData being polymorphic here in the body of the FileData class via a virtual destructor
virtual ~FileData() = default;
Here is the deconstructor for the Directory (derived class)
~Directory() {};
Why won't either method work? Basically I'm trying to do the following
B* = static_cast<B*>(A*)
where B is the derived class and A is the base class.
I have mainly two kinds of compile warning:
1. implicit declaration of function
in a.c, it has char *foo(char *ptr1, char *ptr2), in b.c, some functions use this foo function without any declaration, and I found seems compiler will treat the function foo return value as integer, and even I can pass some variables less or more than foo function declaration
2. enumerated type mixed with another type
My target chip is ARM11, it seems that even I don't solve these two kinds of compile warning, my program can run without any issues, but I believe it must have some risk behind these. Can anyone give me some good example that these two kinds of compile warning can cause some unexpected issues?
Meanwhile, if these two warnings have potential risk, why c compiler allow these kinds warning happen but not set them to error directly? any story behind?
Implicit declaration. E.g. you have function: float foo(float a), which isn't declared when you call it. Implicit rules will create auto-declaration with following signature: int foo(double) (if passed argument is float). So value you pass will be converted to double, but foo expects float. The same with return - calling code expects int, but returned float. Values would be a complete mess.
enum mixed with other type. Enumerated type have list of values it could take. If you trying to assign numeric value to it, there is a chance that it isn't one of listed values; if later your code expects only specified range and presumes nothing else could be there - it could misbehave.
Simple example:
File: warn.c
#include <stdio.h>
double foo(double x)
{
return myid(x);
}
int
main (void)
{
double x = 1.0;
fprintf (stderr, "%lg == %lg\n", x, foo (x));
return 0;
}
File: foo.c
double
myid (double x)
{
return x;
}
Compile and run:
$ gcc warn.c foo.c -Wall
warn.c: In function ‘foo’:
warn.c:5: warning: implicit declaration of function ‘myfabs’
$ ./a.out
1 == 0
Old C standard (C90) had this strange "default int" rule and for compatibility it is supported even in latest compilers.
In Haskell, it is considered good practice to explicitly declare the type signature of your functions, even though it can (usually) be inferred. It seems like this isn't even possible in OCaml, e.g.
val add : int -> int -> int ;;
gives me an error. (Although I can make type modules which give only signatures.)
Am I correct in that this isn't possible to do in OCaml?
If so, why? The type system of OCaml doesn't seem that incredibly different from Haskell.
OCaml has two ways of specifying types, they can be done inline:
let intEq (x : int) (y : int) : bool = ...
or they can be placed in an interface file, as you have done:
val intEq : int -> int -> bool
I believe the latter is preferred, since it more cleanly separates the specification (type) from the implementation (code).
References: OCaml for Haskellers
In general, the syntax to let-bind a value with a constrained type is:
let identifier_or_pattern : constraint = e ...
Applied to a function, you can specify the signature as follows:
let add : int -> int -> int = fun x y -> ...
This is analogous to the syntax required to constrain a module to a signature:
module Mod
: sig ... end
= struct ... end