View unanswered posts | View active topics It is currently Thu Nov 27, 2014 9:36 am






Reply to topic  [ 6 posts ] 
defining procedures and variables as private or public 
Author Message
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post defining procedures and variables as private or public
in future, it would be great if one could define procedures and variables as

public: access by any procedure
- or -

private: access only by procedures of the same (header) file,
in order to protect them from unwelcome read or write

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sat Mar 15, 2008 7:09 pm
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post 
THis is a good suggestion. Thanks.

I think what you're asking for is "local" and "extern" scope on variables / functions declared in "#include" files so that local scope are only visible within the single file. Is this an accurate description of your request?

If so, this is something that I'll add to the list of potential new features development. Realistically it's a "medium term" development item -- i.e. try for sometime in 2008 but beyond the next month.


Sat Mar 15, 2008 10:19 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
hi Dick,
I'm not sure if I understand you quite correctly.
What I meant is e.g., that if you define global variables in a header file, all of these variables can be accessed by the main program (which includes it by #include "filename.h").

Actually only few of them should become published (e.g. as an interface procedure to the header file functions), most of them are needed as header file intern semaphores or help variables for specific calculations.
Otherwise public access to these variables may cause sverere run time mistakes, if their values might have become directly changed by the main program code.
(this is a case I rather would like to post in German, cause my English knowledge is to poor to explain where exactly the problem is)

In Pascal units, I think, they make a difference between "interface" and "implementation", in C++ and Java more common are "public" and "private" .

here is a small example:

Code:
//********************************
// navigator.h
//********************************

//********************************
// PUBLIC
// INTERFACE
//********************************

public short GetMap(int x, int y);             // interface, allowed to access
public void  SetMap(int x, int y, int value); // interface, allowed to access

public bool  CompassExists; // must be initialized once by main program
public float RobotLength;   // must be initialized once by main program
public float RobotWidth;    // must be initialized once by main program


//********************************
// PRIVATE
//********************************

private short Map [MapSize][MapSize];  // no direct access granted, but only by GetMap() or SetMap()

private const short MapSize=30;  // must not be changed ever!  Only for internal use!         
private const short edge=30;    // must not be changed ever!  Only for internal use!         
 
private short maxXYMap;    //  Only for internal calculation use!         
private float maxXYpos;     //  Only for internal calculation use! 

private void InitVariables();  //  Only for internal initialization use! 


//********************************
// CODE IMPLEMENTATION
//********************************

short GetMap(short x, short y)            // may be accessed by main program
{   return Map[x+(MapSize/2)][y+(MapSize/2)];}

void SetMap(short x, short y, short value)  // may be accessed by main program
{   Map[x+(MapSize/2)][y+(MapSize/2)]=value;}


void InitVariables()  // NO ACCESS BY MAIN PROGRAM
{
  int x,y,i;
  for(x=0;x<MapSize;x++)
  {
      for (y=0;y<MapSize;y++)      
      {Map[x][y]=0;}             
  }
  maxXYMap=(int)((MapSize/2)-1);
  maxXYpos=(float)maxXYMap*edge;
  StopMotors();  // this is another public procedure that has been defined elsewhere             
}
     

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sun Mar 16, 2008 6:26 am
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post 
I think we have the same basic understanding of intent. TThe PASCAL public and private interfaces are very similar to "extern" and "static" in C.

the challenge is in the implementation.

After feedback from initial users, ROBOTC was modified so that the paradigm was that a single file represented a complete user program. This worked for the vast majority of end users. The initial solution required two files -- one to store the project definition and settings and a second to store the project source code -- which proved confusing to end users; they would copy the source file to another diredory but not the project file and then wonder why it didn't compile properly or why settings had been lost.

a partial analogy with professional development environments (IDE) is that they typically store a project in a separate folder/directory. My day-to-day use includes use of five IDEs for development of ROBOTC firmware ahd PC source. Two of these get confused when project directories are renamed or copied; typically the "implied library directories" where "#include" files are located get messed up and need to be manually configured.

So, in ROBOTC, the decision was made to optimize for a single file to describe a user's program/project. This is why the "motor / settings" configuration data is stored in the front of the user program rather than in a separate file. It's also why debug breakpoints are no longer saved across an interactive debugging session.

The ROBOTC IDE was also designed as a single compile that recompiles all source code. There is not a separate link phase -- it is built into the compiler. This works well since projects are small and it only takes a fraction of a second to compile everything; and it ensures that there are not a bunch of intermediate unlinked object files required that need to be linked.

Advanced users have wanted a mechanism to split their program across many files and have been using the "#include" file mechanism. This works but confuses the symbol table scope rules from traditional C projects with many separate "*.c" files that are separately compiled. Since everything is compiled at once via "#include", variables are normally known to every file. THe compiler already has variable scoping levels -- you can define the variable "I" at main level and also redefine within a function and compiler will select the appropriate value, you can access a local variable defned in a function outside of the scope of the function. So it would be relatively straightforward to allow for scope rules that kept some variables local to a single file ("static" keyword in C) vs others that are "extern" and globally known. The challenge is how to do this while still masking this complexity from the majority of users who don't need it.

I think the answer will be to introduce a new "#pragma Cfile <filename>" that can be added to the main file. It can be used to define another C file which should be added to the project. Somewhat like the functionality of classical "makefile" to define the files in a project. This pragma will cause file to be compiled but unlike using a "#include" file, will allow for variables with "local" scope that are only known within the C-file.


Sun Mar 16, 2008 12:56 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
hi,
maybe your proposal solves another problem: that of errors at multiple #include "filename.h"

for example, there is a mainfile "main.c",
a math helpfile "math.h",
a display help file "display.h"
a sensors and mux helpfile "sensors.h", and
a navigation help file "navigation.h" ;-)

what, if main.c uses math functions of math.h, sensors.h, display.h, and navigation.h,

sensors.h needs display.h (for compass calibration)

but navigation.h itself uses math.h and sensors.h (for the compass).

You can't always cascade all the header files, there sometimes ar cross-dependencies.

A linker could make it easier, but maybe your #pragma statement solves this, too.

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sun Mar 16, 2008 1:17 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
PS:
as I guess, "extern" is a view from the main file (which requests access to any extern source definition),
while "public" is a definition in the source, which enables access from outside (and "private" excludes any access)

one source is treated like an object,
the other is the subject.

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Tue Mar 18, 2008 8:33 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 6 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.